activity 启动模式_Activity的生命周期和启动模式

v2-bdcc1978ca1207ab62767b526014a10b_1440w.jpg?source=172ae18b

Activity生命周期

图片来源于网络

v2-8a279d1ecfcb09ef7f20d79c20734b6c_b.png

当Activity意外终止(屏幕反转)时Activity会重新创建,其生命周期为:

onPause -> onStop -> onSaveInstance -> onDestroy -> onCreate -> onStart -> onRestoreInstanceState -> onResume

用户可在onSaveInstance中进行数据保存,在onCreate和onRestoreInstanceState中进行数据恢复

// 存储数据

其中onSaveInstanceState方法和onRestoreInstanceState方法只有在activity被异常终止才会调用:

除了屏幕反转导致的Activity重建外,还有由于内存不足导致activity被系统杀死,activity分为以下几种状态:

  1. 前台
  2. 可视
  3. 后台

其中后台activity最易被杀死。

对于屏幕翻转导致的activity重建,可通过configChanges属性进行配置,设定翻转不重建activity:

<activity 
    

常见的configChanges属性还有:

v2-07e59a62aa63abd2840104b798f2f757_b.png

Activity启动模式

<

启动模式有:

  1. standard
  2. singleTop
  3. singleTask
  4. singleInstance

standard

该启动模式为默认启动模式,每启动一个Activity,无论Activity栈中是否有该Activity实例,都会新建一个实例压入Activity栈。

singleTop

会检查Activity栈顶是否存在该Activity实例,若存在则不重新创建,否则重新创建,压入栈。

singleTask

检查整个Activity栈中是否存在该Activity实例,若存在则将其上面的所有Activity出栈以将该Activity移至栈顶,如:

当Aactivity(A所在栈T从栈顶都栈底有ABCD)启动Bactivity时,T栈中的Activity顺序为:BCD。

任务相关性:

  • taskAffinity

被启动的Activity会压入到启动该Activity的Activity的所在栈中,栈的名称一般是该应用的包名,但可通过taskAffinity属性更改:

被启动的Activity设定了taskAffinity值时,当其被启动时则会创建一个名为taskAffinity属性值的栈并将该Activity压入该栈。

需要注意的是:

  1. 名称必须要有.,如:io.github.grooters.demo.firsrTask而不能firstTask,否则报错:
Installation did not succeed.The application could not be installed: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED Installation failed due to: 'null'
  1. 必须配合singleTask,只有配合singleTask才能实现:

在启动另一个Activity时判断当前栈和被启动activity的taskAffinity是否相同,若不相同则将找名称为taskAffinity属性值的栈,没有则创建,然后将该栈移到前台。

如果启动模式为standard,则会出现名称为taskAffinity属性值的栈无法来到前台导致启动了目标activity但不可见。

  • allowTaskReparenting

除了指定栈名称外,还可以配合属性allowTaskReparenting使用:

当应用1的Aactivity启动应用2的Bactivity时,由于启动B的Activity位于应用1中,即其所在的栈名称为应用1的包名,所以Bactivity的栈理应为应用1的包名。但如果allowTaskReparenting设置为true,则会将Bactivity迁移到应用2的栈(若没有设置taskAffinity属性栈名称即为应用2的包名,若设置了则为taskAffinity属性值)中。
  • 图片来源于网络 *

v2-644fb0b57eeb15b790c1aa87f793a84b_b.png
<

Activity的启动标记

常见的有:

  1. FLAG_ACTIVITY_NEW_TASK

等同于singleTask的启动模式,先判断当前栈和被启动activity的taskAffinity是否相同,若不相同则将找名称为taskAffinity属性值的栈,没有则创建,然后将该栈移到前台。

  1. FLAG_ACTIVITY_CLEAR_TOP

将被启动Activity实例前的所有Activity出栈,如果是singleTask则将该实例移至栈顶,否则新建实例放到栈顶。

  1. FLAG_ACTIVITY_SINGLE_TOP

等同与singleTop的启动模式。

可通过以下代码查看栈信息(只能获取前台Activity信息):

adb shell dumpsys activity > activityInfo.txt

隐式启动

通过隐式启动Activity需要在AndroidManefist的Activity的定义中设置intent-filter,其中匹配属性有:

  1. action
  2. category
  3. data

在设置了intent-filter后,想要找到该intent,则需要通过Java代码设置相应action,category,data的值。

action

可在intent-filter中定义多个action,若要找到该intent只需要匹配其中一个action即可

AndroidManefist.xml:

<intent-filter>
     

Java:

intent

category

无法单独通过该属性找到intent,至少需要一个action或data才能找到intent。

可在intent-filter中定义多个category,Java代码中不需要全部实现,但Java代码中添加了的category,需要在AndroidManefist被全部定义,否则报错

由于会在Java代码中默认添加android.intent.category.DEFAULT这个category,所以每次设置intent-filter都需添加上这个category。

<intent-filter>
     

Java:

intent

data

这是一个通过Uri来寻找intent的方式,Uri格式为:

scheme://host:port/path

例如:

http[scheme]://www.lilinlang.github.io[host]:8080[port]/path[path]

其中scheme常见的有:

  1. file

将其设置为scheme,Java代码通过Uri寻找该intent会报错:

java.lang.RuntimeException: Unable to start activity ComponentInfo: android.os.FileUriExposedException:file://... exposed beyond app through Intent.getData()
  1. http
  2. content

该属性寻找intent的规则和action类似,只需与xml中设定的任意一个data匹配都可以找到intent。

除此之外,还需要为Uri设置mineType,常见的mineType:

v2-ff5b6132015e44d632dbd95ec3009e52_b.png

AndroidManefist.xml:

<intent-filter>
     

Java:

intent

判断是否成功找到intent

  1. 通过Intent的resolveActivity方法:
ComponentName 

通过调用该方法若能成功找到该intent,则返回该Activity的ComponentName对象,否则返回null:

拿到ComponentName,可以直接设置启动activity:

Intent 
  1. 通过PackageManager的resolveActivity方法
// 只匹配category为DEFAULT的Activity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值