Activity的深入理解
来源:互联网 发布:中信银行网络贷款利率 编辑:程序博客网 时间:2024/06/07 05:11
Activity异常状态时的生命周期
当Activity在异常情况下需要重新创建时,系统会默认保存当前的Activity视图结构,并且在Activity重启后为我们恢复这些数据,那么针对某一个特定的View,系统能回复哪些数据呢?
通过View的源码可以看到。
关于保存和回复View层次结构,系统的工作流程是这样的:首先Activity被意外终止时,Activity会调用onSaveInstanceState
去保存数据,然后Activity会委托Window去保存数据,接着Window再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶层容器再去一一通知它的子元素来保存数据,这样整个数据保存过程就完成了。可以发现,这是一种典型的委托思想,上层委托下层。父容器委托子元素去处理一件事情,这种思想在Android中有很多应用,比如View的绘制过程、事件分发等都是类似的思想。至于数据恢复过程也是类似。
onSaveInstanceState只会在Activity即将被销毁并且有机会重新显示的情况下才会调用它。
系统只有在异常终止的时候才会调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,其它情况不会触发这个过程。
Activity关于SingleTask启动模式
SingleTask启动模式:栈内复用模式,单实例模式,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,回调onNewIntent方法。具体是当一个singaleTask模式的Activity A请求启动时,系统会现寻找存在它想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放入栈中。如果存在它所需的任务栈,那么看栈中是否存在A,如果存在则清空A上面的任务栈,另A到栈顶,否则创建A并入栈。如果不存在想要的任务栈,但是A存在于不想要的任务栈中,那么仍然通过TaskAffinity制定想要的任务栈启动时,仍然会创建想要的任务栈,然后创建A并入栈。
什么是Activity所需的任务栈呢?取决于TaskAffinity:翻译为任务相关性。
这个参数标识了Activity所需任务栈的名字,默认情况下,所有Activity的TaskAffinity的名字为应用的packageName。TaskAffinity主要和singleTask后者allowTaskReparenting属性配对使用,在其他情况下没有意义。任务栈分为前台任务栈和后台任务栈。
当TaskAffinity和allowTaskReparenting结合的时候,当一个应用A启动了应用B的某个Activity后,如果这个Activity的allowTaskReparenting属性为true的话,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。
根据实际测试,当要从B应用启动某个Activity C,并且它设置了allowTaskReparenting属性为true时,launchMode不设置时,那么Home按键回到桌面,点击B应用,打开的不是B的首界面而是Activity C.
Common是A应用,OneSDK是B应用,蓝色是Activity C,红色是B应用的首界面
当要从B应用启动某个Activity C,并且它设置了allowTaskReparenting属性为true时,launchMode设置为singleTask时,那么Home按键回到桌面,点击B应用,打开的不是B的首界面而是Activity C.
如果不设置B应用的Activity C,那么相同的操作打开的是B应用的首界面,此时查看任务栈,A应用的任务栈最上层是Activity C,B应用的最上层是首界面。
Common是A应用,OneSDK是B应用,蓝色是Activity C,红色是B应用的首界面
当即通过AndroidManifest设置launchMode,同时在Intent中指定了启动模式时,代码中的启动模式优先级更高,也就是Intent方式为准。
但是Intent无法为Activity设置为singelInstance模式,在AndroidManifest无法设置Activity为FLAG_ACTIGITY_CLEAR_TOp标识。
测试实例
定义以下Activity
<activity android:name="com.derek.demo.MainActivity" android:configChanges="keyboard|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTop" android:screenOrientation="sensor" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.derek.demo.MainActivity.SecondActivity" android:configChanges="keyboard|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="sensor" android:taskAffinity="com.derek.task1" > </activity> <activity android:name="com.derek.demo.MainActivity.ThirdActivity" android:configChanges="keyboard|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="sensor" android:taskAffinity="com.derek.task1" > </activity>
将SecondActivity和ThirdActivity都设成singleTask并指定它们的taskAffinity属性为com.derek.task1
,注意这个taskAffinity属性的值为字符串,且中间必须包含包名分隔符”.”。然后进行如下操作:在MainAcitiviy中点击按钮启动SecondActivity,在SecondActiviy中点击按钮启动ThridActivity,在ThridActivity中单击按钮又启动MainActivity,最后再在MainActivity中单击按钮启动SecondActivity,现在按下back键,然后看到那个Activity?
答案是回到桌面。
Activity的Flags
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有这个标记的Activity不会出现在历史Activity的列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。它等同于XML中指定Activity的属性android:excludeFromRecents= "true"
IntentFilter的匹配规则
判断隐式启动Activity的时候,可以做一下判断,查看是否有Activity能够匹配我们的Intent。
PackageManager提供了两个方法如下:
public abstract List<ResolveInfo> queryIntentActivities(Intent intent,int flags);public abstract ResolveInfo resolveActivity(Intent intetn,int flags);
第二个参数flag需要使用MATCH_DEFAULT_ONLY这个标记为,来仅匹配那些在intent-filter中声明了
<category android:name="android.intent.category.DEFAULT" />
第一个方法返回所有匹配的Activity,第二个方法只返回最佳匹配的一个Activity
- Activity的深入理解
- 深入理解Activity的生命周期
- activity的生命周期深入理解
- 深入理解Activity的LaunchMode
- 深入理解Activity的生命周期
- 深入理解Activity的生命周期
- 深入理解Activity的生命周期
- 深入理解Activity的生命周期
- Activity的启动模式的深入理解
- 深入理解 Android Activity的生命周期
- 深入理解 Android Activity的生命周期
- 深入理解 Android Activity的生命周期
- 深入理解Activity的生存期(二)
- Android Activity完整的生命周期深入理解
- 深入理解Activity生命周期的回调
- 深入理解Activity生命周期的回调
- 对activity的生命周期深入理解
- 深入理解Activity
- GUI图形用户界面编程
- Java的四种引用类型与ReferenceQueue
- predictionio执行train、deploy、eval的命令和执行命令后的打印输出分别如下
- Python机器学习应用 | 降维——NMF方法及实例
- 开发android应用时,更换应用图标后没生效
- Activity的深入理解
- 12. Integer to Roman-python
- Win10 装ubuntu 14.04双系统 (uefi引导)
- css通用小笔记03——浏览器窗口变小 div错位的问题
- 前端跨域请求原理及实践
- ubuntu安装ros
- redis系统命令简介笔记(2)
- 桶装水和白开水的缺点
- QT + VS2010 实现中英文切换