Android的生命周期和启动模式

Activity的启动过程是一个很复杂的过程,涉及了Instrumentation ActivityThread AMS(ActivityManagerService)等类。 ActivityThread和AMS之间的通信是跨进程的通信,采用的机制是Binder机制,具体就是利用ApplicationThread binder接口来完成。ApplicationThread是ActivityThread的内部类。

启动Activity的请求会有Instrumentation来处理,之后会通过binder向AMS来发送请求,AMS里面会又个ActivityStack来负责栈内的Activity状态的同步。启动Activity最终会调用到ActivityThread中的scheduleLaunchActivity方法。

有个问题: 当Activity A启动Activity B的时候,A的onPause需要先执行,然后Activity B才会启动。

Activity的生命周期:

生命周期可以分为两种:正常情况和异常情况。
正常情况的生命周期就不说了,主要说下异常的生命周期

当与资源相关的系统配置发生改变以及系统内存不足时,Activity就可能会被杀死,这种情况的生命周期是什么样的,主要讨论这种。
1.我们知道我们可以设置横屏和竖屏的资源,在手机处在横屏和竖屏的情况去不同的文件夹中加载资源,这时Activity就会被重新创建

2.当系统内存不足时,系统也会杀死后台的Activity,当应用回到这个Activity的时候,此Activity又会被重新创建

当异常情况,Activity被杀死的时候,onSaveInstanceState回调方法会被调用,在onStop之前,在此方法中可以保存下数据,当Activity恢复的时候,可以恢复数据。 在Activity被重新创建的是时候,onCreate和onRestoreInstanceState会被调用,且其参数bundle不为空,是Activity被杀死的时候存储的数据。

onSaveInstanceState和onRestoreInstanceState系统为我们有默认实现,可以恢复一些View的状态。每个View也有onSaveInstanceState和onRestoreInstanceState,这两个方法就用于恢复view状态的。

Activity—window—decorview—activity的contentview

前面说到系统内存不足的时候会杀死Activity,杀哪个Activity是根据Activity优先级的。
1.前台Activity,可交互的,优先级最高
2.可见的Activity,但不可交互
3.后台Activity,不可见的最低

当一个应用没有四大组件的时候后台会很快杀死这个进程。

可以通过设置Activity,当资源发生变化的时候不重建Activity。用android:configChanges=“”来设置,例如设置当屏幕方向改变时不重建,就android:configChanges=“orientation”。多个值使用“|”分割。
比较常用的有locale orientation keyboardHidden screenSize

Activity的启动模式

Activity有四种启动模式: standard singleTask singleTop singleInstance

standard:默认模式,可以有多个实例,谁启动了这个Activity,这个Activity就运行在谁的任务栈中。
注:当用Application的Context用标准模式去启动Activity的时候,会报错。因为 Application的Context没有任务栈,只有Activity的Context才有任务栈,而标准方式启动的Activity要运行在Caller的任务栈中,所以报错了。这时可以使用SingleTask方式启动。

singleTop:栈顶复用模式,如果已经有实例在栈顶了,则不会创建新的实例,onNewIntent会被调用,如果栈顶的实例不是此Activity则创建新的实例。

singleTask:栈内服用模式,单例模式 只用Activity在一个栈中存在,则不会重新创建实例,会调用onNewIntent方法

singleInstance: 单实例模式,是singleTask的加强版。只能单独位于一个栈中。

这里要说到一个参数 TaskAffinity,任务相关性。这个参数标志了一个Activity所需要的任务栈的名字,默认情况下所有Activity所需的任务栈的名字是应用的包名,我们可以为每个Activity单独制定TaskAffinity属性,这样就可以运行在新的任务栈了。
TaskAffinity属性需要和singleTask或allowTaskReparenting属性配对使用。其他情况没有意义。

TaskAffinity和singleTask配合使用,可以是Activity在一个新的任务栈中。

TaskAffinity和allowTaskReparenting配合使用,可以是Activity转移
例如:应用A启动了应用B的Activity C,当再次启动应用B的时候,展示的不是launcher界面,而是Activity C。

有两种方式为Activity设定启动模式,manifest和代码动态指定。

用代码的方式的优先级要高于在manifest中指定。

这里介绍一个命令: adb shell dumpsys activity 查看任务栈里面的activity

Activity的Flags

1.FLAG_ACTIVITY_NEW_TASK相当于singleTask
2.FLAG_ACTIVITY_SINGLE_TOP相当于singleTop
3.FLAG_ACTIVITY_CLEAR_TOP清除上面的所有activity,如果是standard的,那么包含自己也清楚,之后在栈顶新建实例
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS不出现在历史列表中,和manifest中android_excludeFromRecents=“true”效果相同。

IntentFilter匹配规则

Activity的启动分为显示和隐式。显示需要指定包名和Activity名。而隐式则通过匹配IntentFilter。
下面只说隐式启动:

IntentFilter的过滤信息有action category data,为了匹配IntentFilter,需要同时匹配action category 和 data信息,否则匹配失败。一个过滤列表中的aciton category data可以有多个,所有的action category data分别构成不同的类别,同一类别的信息共同约束当前类别的匹配过程。只有一个Intent同时匹配action类别、category类别、data类别才算完全匹配,只有完全匹配才能启动成功目标Activity。一个Activity可以有多个IntentFilter,一个Intent只要能匹配一组IntentFilter即可成功启动。

下面分别说各组匹配规则:
aciton:
一个Intent中的action能和IntentFilter的任意一个相同即可匹配成功。如果Intent中没有action,则匹配失败,即Intent中action必须有。

category:如果Intent中设定了category,那么要求不论设置几个,都需要和IntentFilter匹配。同时如果Intent没设置category,在startActivity或startActivityForResult中,会默认给Intent添加category“android.intent.category.DEFAULT”,这样如果IntentFilter中有这个category,也是可以匹配的。

data:
如果IntentFilter定义了data,那么Intent必须匹配。
先说下data的结构

data由两部分组成:mimeType和URI,mineType指媒体类型,比如image/jpeg、audio/mpeg4-generic和vido/*等,可以表示图片文本视频等不同媒体格式,

下面看下URI的结构
://:/[||]
例如:content://com.example.project:200/folder/subject/etc

scheme:URI模式,比如http file content,如果没有指定scheme,那么整个URI无效
Host: URI的主机名。如果没有指定Host,那么URI无效

Port:端口号。仅当URI中指定了scheme和Host,port才有意义

path pathPattern pathPrefix表示路径信息。pathPattern可以使用“*”,表示0个或多个任意字符,pathPrefix表示路径前缀信息

data的匹配规则要求Intent中必须含有data,并且能够完全匹配IntentFilter中的某一个data

IntentFilter中的URI有默认值,是content和file

注意:Intent指定完整data的时候要使用setDataAndType,而不能分开使用setData,setType,因为这两个方法会清空对方的值。

IntentFilter的匹配规则也使用BoradcastReceiver和Service。

可以使用PackageManager中的resolveActivity和queryIntentActivitys判断,intent能否有匹配的Activity

注意:由于在startActivity和startActivityForResult中会默认添加default的category,根据category的匹配规则,可以知道只有IntentFilter声明了default 的category,才能被隐式的调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值