1.Activity的生命周期与启动模式

来源:互联网 发布:ftp默认端口号 编辑:程序博客网 时间:2024/06/05 00:36

1. 生命周期简介


1.1 onCreate

表示Activity正在创建,在其中可以执行一些初始化任务。setContextView方法在其中。

1.2 onRestart

表示Activity重新启动,典型特征:不可见->可见

1.3 onStart

表示Activity正在启动,典型特征:可见,不可交互

1.4 onResume

表示Activity已经可见,典型特征:可见,可交互

1.5 onPause

表示Activity正在停止,典型特征:可见,不可交互,例如:Act上面出现了一个透明的Act2,此时Act1处于onPause状态

1.6 onStop

表示Activity即将停止,典型特征:不可见,不可交互,可做一些轻微重量级的回收任务,不可进行耗时操作。

1.7 onDestory

表示Activity即将被销毁,典型特征:销毁,回收工作,资源释放

2.Act生命周期的切换过程流程图

其他说明:

1. 新Act采用了透明主题,旧Act不会调用onStop方法

2. 生命周期存在3组配对关系和单独的一个onRestart

3. onStart与onResume区别:是否可交互。同理,onPause与onStop之间

4. Act1启动Act2,先调用Act1中的onPause,后调用Act2中OnResume

书中P4~P6源码部分没有理解,有待回顾。

3异常情况下生命周期分析

3.1资源配置引起的Act被杀死并重新创建

简单说,当系统配置发生了变化(横竖屏切换),就会引起Act被杀死并重新创建。

onSaveInstanceState方法与onRestoreInstance-State方法用户在异常情况下存储用户的临时数据,和在重新启动时恢复用户的临时数据。前者的调用时机在onStop之前,后者在onStart方法后被调用,中间通过一个Bundle对象作为参数进行传递。

可以通过①onCreate方法和②onRestoreInstance-State来获取onSaveInstanceState方法中所保存的用户临时数据,二者的区别为:①中使用Bundle需要进行判断null处理,而②不需要判断,可直接使用。原因为②被调用时,一定是有数据可以恢复的。

可恢复的数据包括文本框的用户输入数据,Listview的滚动位置等。当保存用户的临时数据时为上级通知下级,下级进行保存(中间存在多级),View是可以保存数据的。

注意只有在异常情况下才回去调用 onSaveInstanceState方法,onRestoreInstanceState方法

3.2内存不足时,低优先级的应用会被杀死

Act优先级(由高到低)

①前台Act,正在与用户进行交互的Act

②可见非前台Act,例如:Act中弹出了一个对话框

③后台Act,已经被暂停的Act

一个进程没有四大组件在执行,那么该进程会快就会被系统杀死

防止屏幕旋转导致的Activity被系统杀死,需要在AndroidMenifest.xml中配置android:config-Changes=“orientation|screenSize”(其中screen-Size是在api13后需要添加的),此时当屏幕方向旋转了,不会再调用onSave-InstanceState方法与onRestoreInstanceState方法,仅仅调用onConfi-guration,在其中我们可以做一些自己的处理

2. Activity的启动模式


2.1 standard:标准模式 ,特点每次启动Act时都会创建一个实例,新启动的Act一般与原来的启动者的同属于一个任务栈

2.2 singleTop:栈顶复用模式,特点:栈顶唯一,如果新启动的Act恰好处于栈顶,那么不会创建新的实例,会调用onNewIntent方法

2.3 singleTask:栈内复用模式,特点:栈内存在实例则不创建新的实例,将本身移动到栈顶,原来在其之上的Act将进行出栈处理,即具有clearTop的作用。复用时也会调用onNewIntent方法。

singleTask流程图

singleTask流程图

2.4 singleInstance:单实例模式,具有singleTask的所有特性,具有此模式的Act只能单独的存在在一个任务栈中。当启动一个单实例模式Act,为其创建一个任务栈,后续的启动Act都会使用该实例,直到该实例被销毁,与此同时相应的任务栈也会被销毁。

2.5 TaskAffinify任务相关性,主要用于singleTask,allowTaskReparenting属性配对使用

默认情况下所有的Activity所需的任务栈的名字为应用的包名。我们可以为每个Activity单独指定TaskAffinify

任务栈分为:前台任务栈(当前与用户交互的)和后台任务栈

allowTaskReparenting属性为true时标明该Act可跨Task例:AppA—>appB(Page c)—>back->点击桌面B,显示的是pageC,而不是B的主界面

当代码中设定了addFlag属性时,其优先级高于AndroidMenifest.xml中配置launchMode

当学习act任务栈时,应该使用adb shelle dumpsys activitys来查看当前的Act

3. Activity的Flag


①FLAG_ACTIVITY_NEW_TASK:相当于”singleTask”

①FLAG_ACTIVITY_SINGLE_TOP:相当于”singleTop”

①FLAG_ACTIVITY_ClEAR_TOP:当具有Flag启动的Act启动时,会将栈中其上的Act进行出栈,一般与NEW_TASK一起使用。singleTask默认具有该属性

①FLAG_ACTIVITY_EXClUDE_FROM_RECENTS:不会出现在历史Act列表中,相当于AndroidMenifest.xml中配置android:excludeFromRecents-=”true”

4. IntentFilter的匹配规则


Intent不应该既是隐式调用又是显式调用,如果二则并存的话以显式调用为主。

  • 隐式调用需要匹配IntentFilter(category,action,data)
  • 说明: 一个Activity可以拥有多个IntentFilter,多个IntentFilter之间是”或”关系,只要满足其中的一个IntentFilter就可以启动当前的Activity;而actiong,category,data类别间是与关系,必须全满足才可以。
  • 具体匹配规则如下:
1. action:
  Intent中的字符串与IntentFilter中完全一致才视为匹配成功,多个action-,仅满足一个匹配成功即可。如果没有指定,action,那么匹配失败。action要求必须存在且必须=和过滤规则中的其中一个相同,区分大小写。
2.category的匹配规则:
  要求Intent中满足IntentFilter中的所有的category才算匹配成功。startActivity和startActivityForResult中默认对intent添加了android.intnte.category.DEFAULT这个属性。所以为了是Activity能够接受隐式调用,就必须在intent-fil,ter中指定android-intent-category.DEFAULT这个属性。
3.data的匹配规则:
  与action类似,如果过滤规则中定义了data,那么Intent中必须也要有定义可匹配的data。
  data的结构:mimeType(媒体结构)和URI
#####  URI结构:\://\:\/[\|\|\]
例如:content:..com.example.project:200/folder/subfloder/etc
   http://www.baidu.com:80/search/info
  Scheme:URI的模式:http、file、content等,如果URI中没有Scheme,那么整个URI其他参数都是无效的,即该URI是无效的。HOST:主机名,必须有。Port:端口号,只有指定了Scheme,HOST时,Port才有效。path,pathPattern,pathPrefix表示路径信息。URI的默认值为:content/file。注意:使用intent传递date,type时,不能仅仅调用setType,setData,因为他们各自调用会清空对方,所以要使用setdataAndType方法。data支持合并,拆分的写法。
IntentFilter的匹配规则对Service和BroadcastReceiver也是使适用的。不过系统建议调用Service时,使用显示的调用方式。
  在使用intent隐式调用activity时,应该先调用PackageManager的resolveActivity方法或者Intent的resolveActivity的方法,如果找不到就会返回null。调用方法时,第二个参数传递为:MATCH_DEAFAULT_ONLY,这个标记表明仅仅查找声明了android.intent.category.DEAFAULT的ACtivity。
0 0
原创粉丝点击