Activity生命周期+启动模式+启动方式
Activity的生命周期+启动模式+启动方式
1. Activity的生命周期
Tips:用户打开新的Activity是或者会桌面的时候,回调:onPause ->onStop。如果新的activity采用了透明的主题,那么当前的activity不会回调onStop方法。
Tips:Activity的onSaveInstanceState(调用时机是在onStop之前)和onRestoreInstanceState只在activity异常中止时调用,用来存储和回复数据。
Tips:Activity的跳转(a->b)会先执行a.onPause->b.oncreate->b.onstart->b.onresume->a.onstop。
所以在onpause中不要执行大量的操作,否则会导致跳转出现卡顿现象,一般放在onstop中就好。
Tips:横竖屏切换防止activity销毁重新创建,配置加android:configChanges="orientation ">属性。此时activity的onConfigurationChanged的方法会调用。
configChanges属性常用含义列表:
配置 | 含义 |
locale | 设备的本地位置发生了改变,一般是切换了系统的语言 |
keyboard | 键盘类型发生了改变,一般用户使用了外接键盘 |
keyboardHidden | 键盘的可访问性发生了改变,一般是用户调出了键盘 |
screenLayout | 屏幕布局发生了改变,一般是用户使用了另一个显示设备 |
orientation | 手机的屏幕方向发生了改变,比如横竖屏切换 |
screenSize | 屏幕的尺寸发生了改变,旋转屏幕事,屏幕尺寸会改变,minsdkversion和targetsdkversion低于13,不会导致重启,否则导致重启,sdk13新添加的属性 |
2. Activity的启动模式
1. standard:标准模式
每次启动一个标准模式的activity的时候,任务栈都会重新创建一个实列放入栈中,符合典型情况下的生命周期。
Tips:启动标准模式的activity会把它放到和启动它的activity栈中。
问题来了:singleInstance模式下的activity启动时,放到哪里呢???读者可以自己试试
2. singleTop:栈顶复用模式
每次启动singleTop模式的activity,先判断栈顶是否有此activity实例,如果有调用onNewintent方法,如果没有则重新创建一个实例。
3. singleTask:栈内复用模式
这是一种单实列模式,只要activity在一个栈中存在,每次启动此activity都不会重新创建实例。只会调用onNewIntent方法。启动一个singleTask模式的activityA,系统首先判断是否有A想要的任务栈,如果没有,则创建一个,并且把A的实例放入栈中。如果存在A所需的任务栈,则判断是否存在该实例,没有则创建,有系统会把它调到栈顶并调用onNewIntent方法。
Tips:singleTask模式具有clearTop的效果,例:如果栈中存在abcd四个activity实例,此时启动b,会使cd出栈,此时栈中只有ab。
4. singleInstance:单实例模式
singleInstance模式是一种加强版的singleTask模式,具有singleTask的所有特性。加强了一点,这种模式的activity只会存在单独的任务栈中。除非系统销毁了这个任务栈,由于栈内复用,后续不会在创建实例。
Tips:android:taskAffinity="栈名"属性主要和singleTask模式或者allowTaskReparenting属性配对使用,其他情况下没有意义。栈名不要和包名相同,否则没有任何意义。特殊说明:taskAffinity和allowTaskReparenting同时使用。A应用启动b的一个activity后,如果这个activity的allowReparenting为true,次实启动b,会显示刚刚启动的那个activity。
查看activity的栈信息命令:adb shell dumpsys activity
打印当前包名app的activity栈信息:adb shell dumpsys activity | grep com.xxx.xxx.xx
大厅当前正在运行的activity信息:adb shell dumpsys activity | grep mFocusedActivity
3.Activity的启动方式及intent的匹配规则
3.1 Intent的匹配规则
示例:
<intent-filter>
<actionandroid:name="com.lz.test1"/>
<actionandroid:name="com.lz.test2"/>
<categoryandroid:name="com.lz.catest1"/>
<data android:host="abc"
android:scheme="file "
android:path="/string"
android:pathPrefix="/string"
android:mimeType="text/plain"/>
</intent-filter>
说起intent的匹配规则就必须说起intentFilter拦截器,intentFilter含有参数action,category,data。
action:必须红拦截器中的其中一个完全匹配,区分大小写。
category:必须和拦截器中的一个完全匹配,区分大小写。略有不同的是category可以不用设置,intent默认添加intent.category.DEFAULT这个默认category。
data:data=mimeType + URI。
mimeType:指媒体类型,例如:image/jpeg,video/*等,可以表示图片、文本、视频等不同媒体类型。
URI:结构:<scheme>://<host>:<port>/<path>|(或者)<pathPrefix>|(或者)<pathPattern>
例如:content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
Scheme:比如http、file、content等。uri中没有指定scheme,整个uri是无效的。
Host:uri的主机名。uri中没有指定host,整个uri是无效的。
Port:uri中指定了Scheme和Host时,potrt才有意义。
Path+PathPattern:表示完整的路径信息。但是pathPrefix中可以含有正则表达式。
pathPrefix:*(乘)表示匹配0次或更多。如l*,可以匹配 l ll lll …,
.(点)可以匹配任意字符,.*(点心)可以匹配任意字符任意多次。
*的使用要用转义//*,/要用 ////
PathPrefix:路径的前缀信息也就是路径的开头部分例如:/folder或者/search。
1.显示启动activity
使用startActivity(new Intent(context,activity.class));,比较简单就不多说了
2.隐示启动activity
使用实例:
Intent intent =new Intent("intentFilter中定义的action”);
Intent.addCategory(“intent中定义的category,可以不写,用默认的”);
Intent.setDataAndType(Uri.parse(“file://abc”),”text/plain”);
startActivity(intent);
Tips:同时设置mimeType和data时,必须调用setDataAndType。setData会清空其中的mimeType,setMimeType会清空其中的data。
网页启动app
<intent-filter>
<actionandroid:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<categoryandroid:name="android.intent.category.BROWSABLE" />
<data
android:host="com.lz.test "
android:scheme="lztest"/>
</intent-filter>
启动地址设置:lztest://com.lz.test/?data1=data1&data2=data2,多个参数用&分割。代码中
使用uri.getQueryParameter获取传入的参数。
最近同事在学习微信小程序,如果有感兴趣的欢迎加QQ群:221725135