Android开发艺术探索(一)Activity的生命周期和启动模式

1.1  Activity的生命周期全面分析

    1.1.1  典型情况下的生命周期分析

在正常情况下,Activity会经历如下生命周期。

(1)onCreate:表示Activity正在被创建;创建一个Activity时首先执行此方法,在这个方法中我们可以做一些初始化工作。

(2)onRestart:表示Activity正在重新启动;一般当当前的Activity从不可见重新变为可见状态时,此方法会被调用。

(3)onStart:表示Activity正在被启动;此时Activity已经“可见”,但没有出现在前台,无法与用户进行交互。

(4)onResume:表示Activity已经可见了;此时Activity已经可见,已经出现在前台,可与用户进行交互。

(5)onPause:表示Activity正在停止;因为此方法执行时间很短,所以不能做太耗时的操作。

(6)onStop:表示Activity即将停止;执行此方法时可以做一些重量级的回收资源的工作,也不能过于耗时。

(7)onDestroy:表示Activity即将被销毁;做一些回收工作和最终的资源释放。

注意:onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这种区别,在实际使用中没有其他明显区别;而用户从当前Activity打开一个新的Activity时,先执行原活动的onPause,再执行新活动的onResume。

    1.1.2  异常情况下的生命周期分析

        1.资源相关的系统配置发生改变导致Activity被杀死并重新创建

比如说当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重建。

Activity被销毁时,其onPause、onStop、onDestroy均会被调用。

同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。

当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。

2.资源内存不足导致低优先级的Activity被杀死

Activity的优先级:前台Activity > 可见但非前台Activity(例如在对话框下的Activity) > 后台Activity。

保证后台有一定优先级:将后台工作放入Service中。

3.如何设置在系统配置改变后,Activity不被重新创建

    android:configChanges="orientation"
configChanges 部分常用项目和含义
项目含义
locale设备的本地位置发生了改变,一般指切换了系统语言
orientation屏幕方向发生了改变,比如旋转了手机屏幕
keyboardHidden键盘的可访问性发生了改变,比如用户调出了键盘

通过设置后,Activity的确没有重新创建,并且也没有调用onSaveInstanceState和onRetoreInstanceState来存储和恢复数据,取而代之的所系统调用了onConfigurationChanged方法。

 

1.2  Activity的启动模式

    1.2.1  Activity的LaunchMode

四种启动模式

(1)standard:标准模式(默认模式)。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。

(2)singleTop:栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。

(3)singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent。同时singleTask默认具有clearTop的效果。

(4)singleInstance:单实例模式。这是一种加强的singleTask模式,它除了具有singleTask模式的所以特性外,还加强了一点,即当A启动时,系统会为它单独创建一个新的任务栈,然后A独自在这个新的任务栈中。

为Activity指定启动模式

第一种是通过AndroidManifest为Activity指定启动模式:

    <activity
        android:name="com.ryg.chapter_1.SecondActivity"
        android:configChanges="screenLayout"
        android:launchMode="singleTask"
        android:label="@string/app_name"
    />

另一种情况是通过在Intent中设置标志位来为Activity指定启动模式:

    Intent intent = new Intent();
    intent.setClass(MainActivity.this, SecondActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
两种指定方式的区别
 AndroidManifestIntent
优先级
限定范围无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识无法为Activity指定singleInstance模式

    1.2.1  Activity的Flags

FLAG_ACTIVItY_NEW_TASK

这个标记位的作用是为Activity指定“singleTask”启动模式,其效果和在XML中指定该启动模式相同。

FLAG_ACTIVITY_SINGLE_TOP

这个标记位的作用是为Activity指定“singleTop”启动模式,其效果和在XML中指定该启动模式相同。

FLAG_ACTIVITY_CLEAR_TOP

具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。这个标记位一般会和singleTask启动模式一起出现,在这种情况下,被启动Activity的实例如果已经存在,那么系统就会调用它的onNewIntent。如果被启动的Activity采用standard模式启动,那么它连同它之上的Activity都要出栈,系统会创建新的Activity实例并放入栈顶。singleTask启动方式默认具有此标记位的效果。

 

1.3  IntentFilter的匹配规则

    1.3.1  action(动作测试)的匹配规则

action的匹配要求Intent中的action存在且必须和过滤规则中的其中一个action相同,这里需要注意它和category匹配规则的不同。另外,action区分大小写,大小写不同字符串相同的action会匹配失败。

    1.3.2  category(类别测试)的匹配规则

category是一个字符串。category的匹配规则要求Intent中如果含有category,那么所以的category都必须和过滤规则中的其中一个category相同。换句话说,Intent中如果出现了category,不管有几个category,对于每个category来说,它必须是过滤规则中已经定义了的category。

为了Activity能够接收隐式调用,就必须在intent-filter中指定“android.intent.category.DEFAULT”这个category。

    1.3.3  data(数据测试)的匹配规则

data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。

data由两个部分组成,mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、 视频等不同的媒体格式,而URI包含参数如下:

URI中各数据的含义
参数解释
SchemeURI的模式,比如http、file、content等,如果URI没有指定scheme,那么整个URI的其他参数也是无效的
HostURI的主机名,比如www.baidu.com,如果host未指定,结果同scheme
PortURI的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的

Path/pathPatten/pathPrefix

表示路径信息

    举例:

过滤规则如下

    <activity
        android:name="com.ryg.chaprter_1.ThirdActivity"
        android:configChanges="screenLayout"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:taskAffinity="com.ryg.task1">
    <intent-filter>
        <action android:name="com.ryg.charpter_1.c"/>
        <action android:name="com.ryg.charpter_1.d"/>
        <category android:name="com.ryg.category.c"/>
        <category android:name="com.ryg.category.d"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    </activity>

完全匹配的Intent

    Intent intent = new Intent("com.ryg.charpter_1.c");
    intent.addCategory("com.ryg.category.c");
    intent.setDataAndType(Uri.parse("file://abc"), "text/plain");
    startActivity(intent);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值