Activity
前言
本文通过官方文档学习,简单的过一遍Activity的基本用法。如果想更深层次的认识Activity应当从应用的启动流程,从管理,界面和控制等多个方面认识Activity更深层次的理解。
Activity的概述
Activity 提供窗口供应用在其中绘制界面。此窗口通常会填满屏幕,但也可能比屏幕小,并浮动在其他窗口上面。通常,一个 Activity 实现应用中的一个屏幕。例如,应用中的一个 Activity 实现“偏好设置”屏幕,而另一个 Activity 实现“选择照片”屏幕。
简而言之:Activity是一个应用的一个“界面”,你可以在它上绘制,处于用户交互内容
AndroidManifest.xml理解(配置清单)
配置清单
要使应用能够使用 Activity,您必须在清单中声明 Activity 及其特定属性。(如果你需要运用四大组件都要配置清单文件)
<-- 是否允许系统备份–>
android:allowBackup=“true”
<-- 应用图标–>
android:icon="@mipmap/ic_launcher"
<-- 应用名称–>
android:label="@string/app_name"
<-- 圆图标–>
android:roundIcon="@mipmap/ic_launcher_round"
<-- 布局从右到左(拉丁语言从左右到右)–>
android:supportsRtl=“true”
<-- 设置主题value下theme–>
android:theme="@style/Theme.TestProvider">
声明 Activity(静态注册)
要声明 Activity,请打开清单文件,并添加 元素作为 元素的子元素。例如:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
此元素唯一的必要属性是 android:name,该属性用于指定 Activity 的类名称。您也可以添加用于定义标签、图标或界面主题等 Activity 特征的属性。如需详细了解上述及其他属性,请参阅 元素参考文档。
显示意图
显示意图:一般是用来应用内组件的跳转。
根据Activity(四大组件)的完全限制(具体)类名,去跳转。
Intent intent=new Intent(this,OtherActivity.class);
startActvity(intent);
显示意图跳转第三方应用
利用第三方应用打开网址:
com.android.browser/.BrowserActivity
//ComponentName=包名/类的路径名称。如果类前面的包名,所在包跟包名是一样的话可以省略包名。
Intent intent=new Intent();
intent.setClassName(“com.android.browser”,“com.android.browser/.BrowserActivity”);
startActvity(intent);
隐式意图
隐式意图:一般是用来应用之间组件的跳转。
根据Intent-filter(意图过滤器)的内容来跳转Activity
Intent intent=new Intent();
intent.setAction(“过滤名”);
intent.addCategory(“类别名”);
startActvity(intent);
Intent-filter
<-- 主入口 --> <-- 在界面注册图标 --> 如果有两个入口,会有两个图标入口。显示隐式跳转第三方应用
可以通过多个不同intent-filter去跳转页面。根据不同意图过滤去跳转页面,根据意图过滤传递不同的数值。
网址的搜索界面
Intent intent=new Intent();
intent.setAction(“android.intent.action.SEARCH”);
intent.addCategory(“android.intent.category.DEFAULT”);
intent.setPackage(“com.android.browser”);
startActvity(intent);
基本数据类型传递
intent.putExtra(“key”,value);
Intent中以键值对的方式保存数据。value为八种基本数据类型
在跳转界面:
getIntent.getIntExtra(“key”);根据key来返回数据i。
对象传递
intent.putExtra(“key”,Parcelable value);
对象必须实现Parcelable接口。(直接Alt+Enter由软件实现);
intent.getParcelableExtra(“key”);
解析对象。
Parcelable 和 Bundle
Parcelable 和 Bundle 对象可跨进程边界使用,例如与 IPC/Binder 事务之间,带有 intent 的 Activity 之间等,还可以用来存储跨配置更改的瞬时状态。
在进程之间发送数据与在 Activity 之间发送数据类似。不过,在进程之间发送时,我们建议您不要使用自定义 Parcelable。如果您将一个自定义 Parcelable 对象从一个应用发送到另一个应用,则需要确保发送和接收的应用上都存在版本完全相同的自定义类。通常情况下,这可能是在两个应用中都会使用的通用库。如果您的应用尝试向系统发送自定义 Parblelable,则可能会发生错误,因为系统无法对其不了解的类进行解组。
例如,某个应用可能会使用 AlarmManager 类设置闹钟,并对闹钟 intent 使用自定义Parcelable。当闹钟响铃时,系统会修改 intent 的 extra Bundle 以添加重复计数。此修改可导致系统从 extra 中剥离自定义 Parcelable。这种剥离进而会导致应用在收到修改后的警报 intent 时崩溃,因为应用预计会收到 extra 数据,而它已不存在。
Parcelable 和 Serialiable
parcelable:存储到内存当中,虽应用的关闭而回收。(速度快)
Serialiable:存储到sd卡当中,效率慢。
跳转一些例子
实现打电话功能
需要权限 Intent intent=new Intent(); intent.setAction("android.intent.action.CALL"); intent.addCategory("android.intent.category.DEFAULT"); Uri uri=Uri.parse("tel:10086"); intent.setData(uri); startActvity(intent);Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse(“tel:10086”);
startActvity(intent);
模拟发短信内容
Intent intent=new Intent();
intent.setAction(“com.example.sendmsg.SEND”);
intent.addCategory(“android.intent.category.DEFAULT”);
Uri uri=Uri.parse(“msg:发短信号码”);
intent.setData(uri);
intent.putExtra(“targeNumKey”,10086);
startActvity(intent);
接收信息
Intent intent=getIntent();
intent.getIntExtra(“targeNumKey”);//10086
intent.getData; //msg:发短信号码(String.replace去掉msg:)
Activity数据回传
数据回传是什么?比如我们点击充值按钮,跳转到第二界面进行充值,充值完成后告诉第一个界面结果。
Intent intent=new Intent(this,SecondActivity.class);
startActivityForResult(intent,requestCode);//请求码
重写onActivityResult(requestCode请求码,resultCode结果码,Intent 返回数据)方法 根据请求码和结果码实现逻辑 数据
setResult(resultCode结果码,Intent 返回数据)
数据回传例子
第三方应用打开系统相机数据回传
Intent intent=new Intent();
intent.setAction(“android.media.action.IMAGE_CAPTURE”);
intent.addCategory(“android.intent.category.DEFAULT”);
startActivityForResult(intent,requestCode);//请求码
根据源码得到结果处理的结果码值resultCode:
Activity.RESULT_OK,Activity.RESULT_CANCLE来处理结果
data.getParcelableExtra(“data”);//Bitmap对象
设置到ImageView当中
生命周期方法
官方文档
生命周期方法一般时成对出现的:onCreate和onDestory,onStart和onStop,onResume和onPause
onCreate和onDestroy方法
创建和销毁
onCreate方法:创建,创建View和绑定数据等工作
onDestroy方法:销毁,释放资源等。
比如我们发送短信是不小心按返回键销毁Activity,这时编辑的短信都不见了。我们在onDestroy中同SharePreferences中保存。在编辑短信时,通过SharePreferences中获取,并将数据设置到编辑框。
onStart和onStop方法
是否可见(setContentView视图相关的)
onStart可以看见,但不可以交互。
onPause不可见。
比如:看电影的时候,突然有人给你打电话。这时,你的电影页面不可见,电影一直在播放,那么对方可能听到你电影的声音。
onStart方法中播放,onStop方法中停止播放。
onResume和onPause方法
都可见,是否获取焦点(onClick事件,onEvent事件等)
onResume获取焦点,可以交互。
onPause失去焦点,不可以交互。
生命周期的一些例子
onCreate–onStart—onResume–onPause–onStop—onDestroy
横竖屏切换
onCreate–onStart—onResume(横竖屏切换)–onPause–onStop—onDestroy–onCreate–onStart—onResume(会执行一次生命周期)
当我们横竖屏切换时,Activity会销毁,并且重新创建
Home和后退
后退:onCreate–onStart—onResume–onPause–onStop—onDestroy
Home:onCreate–onStart—onResume–onPause–onStop
跳转第二个界面
不透明界面:
A:onCreate–onStart—onResume–onPause–onStop
B:onCreate–onStart—onResume
透明界面():
A:onCreate–onStart—onResume–onPause
B:onCreate–onStart—onResume
指定屏幕方向和设置配置信息改变
横竖屏切换带来的问题:
- 游戏开发
- 视频播放器(达到更好的播放效果)
- 其他方式
我们看视频时,我们竖屏看到了一半,这时想放大(横屏)来观看视频。
数据丢失。(对象也不一样了)
指定屏幕方向(禁止旋转)游戏
设置—>显示—>保持纵向或保持横向。
或者在AndroidManifest中activity属性设置
android:screenOrientation=“landscape”
设置信息改变(对配置不敏感)视频播放器
在AndroidManifest中activity属性设置
android:configChanges=“keyboardHidden|screenSize|orientation”
键盘,屏幕大小,方向改变对activity不敏感。
Activity的启动模式
activity采用栈的形式进行存储Activity对象
栈:先进后出
队列:先进先出(Handler–Message)
standard(标准)
栈的代码:单向链表。
标准栈模式储存activity对象。即为"先进后出"的方式。放一个半封闭的"水瓶"的方式,最先进入的只能最后出来。
例子:由4个Activity A,B,C,D。A为程序入口,A跳转B,在跳转C,再跳转D。
这时候“水瓶”从上往下依次放着“CBA”,这时候按返回键销毁D,就打开了C,这是水瓶放着BA,以此类推,直至app销毁。
singleTop
singletop模式:Activity处于栈顶时,不需要重新创建Activity。
例子:由4个Activity A,B,C,D。A为程序入口,B为singletop模式,其余为standard模式。打开次序ABCB,ABCDB。最后没跳转到B时,水瓶分别为:BA,CBA。由于CBA栈顶不是B,所以第一个不用创建B的Activity,而第二个需要创建BActivity。
singTask
singTask模式:Activity为singTask模式,当打开Activity时,Activity以上的栈全部去掉。直接打开Activity,不需要重新创建。只有一个实例。
例子:由4个Activity A,B,C,D。A为程序入口,B为singleTask模式,其余为standard模式。打开次序ABCB,ABCDB,ABCDCDCDB。最后跳转到B时,水瓶分别为:BA,CBA,DCDCDCBA。这时跳转到B都不用创建ActivitiyB,除非内容过大导致B销毁,当跳转到B时,水瓶为:A,A,A。
SingleInstance
singleInstance模式:重新开一个任务栈。任务栈与先前栈关系为栈的关系。
例子:由4个Activity A,B,C,D。A为程序入口,B为singleInstance模式,其余为standard模式。打开次序ABCD,ABCDA,ABCDCDCD。按返回键销毁Activity时,水瓶分别为:Bc-a,Ba-d-c-a,Bd-c-d-c-d-c。销毁玩c-a栈,再销毁B栈