Android四大组件之Activity

Android四大组件之Activity

总结下自己对Activity的理解,首先个人觉得要想弄白一件事,那么就因该从源头开始,好了,废话不多说了,先从Activity框架说起吧

Activity框架和管理结构

  • Activity管理的核心是AcitivityManagerService,是一个独立的进程

  • ActiveThread是每一个应用程序所在进程的主线程,循环的消息处理

  • ActiveThread与AcitivityManagerService的通信是属于进程间通信,使用binder机制

    binder机制,我会在后面的“Android插件化机制”上来详细说明
    

这里写图片描述

Activity启动过程

以启动一个应用程序startActivity为例看一下代码执行的大概流程:

这里写图片描述

可将其分为6个过程:

  1. 使用代理模式启动到ActivityManagerService中执行

  2. 创建ActivityRecord到mHistory记录中

  3. 通过socket通信到Zgote相关类创建process

  4. 通过ApplicatonThread与ActivityManagerService建立通信

  5. ActivityManagerService通知ActiveThread启动Activity的创建

  6. ActivityThread创建Activity加入到mActivities中并开始调度Activity执行

请看下图:

这里写图片描述

并不是所有启动一个Activity都是这样的过程:一个应用程序中所有Activity只有一个ActivityThread属于一个Process,ActivityStack并不是每次都需要创建一个Stack来管理Activities。

下面看看adnroid系统中四个重要概念:

  • Application:由多个相关的松散的与用户进行交互Activity组成,通常被打包成apk后缀文件中

  • Activities:应用程序的主要组成部分,是应用程序的核心

  • ActivityStack:将应用程序中打开的Activity保存在历史栈中,按照栈的先进后出的原则,Start Activity时入栈,返回时出栈

  • Task:将一系列相关的Activity组合,完成某个应用程序完整操作,不管activity属于哪个Application的

例如:写信息—调用—文件管理,都属于一个Task,但属于两个Application

Activity启动流程类结构分析

ActivityService相关类

使用了Proxy代理模式:ActivityManagerProxy代理ActivityManagerService,并为之提供了公共的访问接口:IActivityManager

这里写图片描述

Activity启动

这里写图片描述

ActivityStack管理

ActivityStack创建并存储系列创建的Activity实例,将其入栈管理mHistory

这里写图片描述

ActivityThread

这种管理在应用进程的主线程的执行,在活动管理器请求时调度和执行活动,广播和其他操作,是应用程序的主线程,消息循环执行者;其中有很多的内部类来完成工作。

  • ActivityThread使用内部类:ApplicationThread与ActivityManagerService进行通信,

  • ActivityThread将状态变化传递控制客户端Activity的状态执行;

  • mActivities保存由ActivityStack所创建的ActivityRecord相关实例引用;

这里写图片描述

到这里是对Activity工作机制,以下开始对Activity生命周期解刨。

Activity生命周期

这里写图片描述

如图可以看出,Activity生命周期的走势,从onCreate开始到onDestory在不同场景下的走势情况

图中需要注意一下几点:

  • Activity实例是由系统自动创建,并在不同的状态期间回调相应的方法。一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。称之为entire lifetime。

  • 当执行onStart回调方法时,Activity开始被用户所见(也就是说,onCreate时用户是看不到此Activity的,那用户看到的是哪个?当然是此Activity之前的那个Activity),一直到onStop之前,此阶段Activity都是被用户可见,称之为visible lifetime。

  • 当执行到onResume回调方法时,Activity可以响应用户交互,一直到onPause方法之前,此阶段Activity称之为foreground lifetime。

A-Activity to B-Activity之间的交互

如下图:
这里写图片描述
![A to B](E:\QQPCmgr\Desktop\my_work\Android_Activity\A-Activity-home.png)</br>
这里写图片描述

从这第三幅图中可知道,其他两图是一个正常Activity的流程

A to B 将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。

B to A 将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。

到这里相信大家对Activity的生命周期有所了解,不懂的请动手打印下日志即可看出,Activity生命周期不难理解,而且也很直观,下面加入Activity启动模式来让你的Activity显得更加得心应手。

Activity启动模式

Activity的启动模式分为四种

standard

标准 - 默认模式,在不指定启动模式的前提下,系统默认使用该模式启动活动,每次启动一个活动都会重写创建一个新的实例,不管这个实例存不存在。这种模式下,谁启动了该模式的活动,该活动就属于启动它的活动的任务栈中这个活动它的的onCreate(),在onStart(),的onResume()方法都会被调用。

    配置形式: <activity android:name=".MainActivity" android:launchMode="standard" />

singleTop

栈顶复用模式,如果新的这个活动已经位于栈顶,那么活动不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该活动的实例,则情况与标准模式相同需要注意的是这个活动它的的onCreate(),在onStart()方法不会被调用,因为它并没有发生改变。

    配置形式:<activity android:name=".MainActivity" android:launchMode="singleTop" /> 

singleTop模式分3种情况

1、当前栈中已有该活动的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将意图对象传入,回调onNewIntent方法

2、当前栈中已有该活动的实例但是该实例不在栈顶时,其行为和标准启动模式一样,依然会创建一个新的实例

3、 当前栈中不存在该活动的实例时,其行为同标准启动模式

标准和singleTop启动模式都是在原任务栈中新建活动实例,不会启动新的任务,即使你指定了taskAffinity属性。
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。

  • 这个参数标识了一个活动所需任务栈的名字,默认情况下,所有活动所需的任务栈的名字为应用的包名

  • 我们可以单独指定每一个活动的taskAffinity属性覆盖默认值

  • 一个任务的亲和力决定于这个任务的根活动(根活动)的taskAffinity

  • 在概念上,具有相同的亲和力的活性(即设置了相同taskAffinity属性的活动)属于同一个任务

  • 为一个活动的taskAffinity设置一个空字符串,表明这个活动不属于任何任务。

很重要的一点taskAffinity属性不对标准和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的任务(如果不指定即默认值,即包名)

    指定方式如下:<activity android:name=".ActivitySingleTop" android:launchMode="singleTop" android:taskAffinity="packageName"/>

singleTask

栈内复用模式,这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个活动的实例就会复用这个活动,不管它是否位于栈顶,复用时,会将它上面的活性全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。

    配置形式:<activity android:name=".SingleTaskActivity" android:launchMode="singleTask" >

singleTask启动模式启动活动时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈

  • 如果不存在,则会创建一个新的任务,并创建新的活动实例入栈到新创建的任务中去

  • 如果存在,则得到该任务栈,查找该任务栈中是否存在该活动实例

  • 如果存在实例,则将它上面的活动实例都出栈,然后回调启动的活动实例的onNewIntent方法

  • 如果不存在该实例,则新建活动,入栈并
    此外,我们可以将两个不同应用程序中的活动设置为相同的taskAffinity,这样虽然在不同的应用中,但是活动会被分配到同一个任务中去。

  • 如果指定了相同的taskAffinity的Activity被启动到了同一个任务中

singleInstance

全局唯一模式, 该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的活动会单独占用一个任务栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的活动实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的活动在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。

    配置形式:<activity android:name=".singleinstance.SingleInstanceActivity" android:launchMode="singleInstance" >

如果系统中不存在该实例,所以新建了一个Task,按home键后,使用另一个App进入该Activity,由于系统中已经存在了一个实例,不会再创建新的Task,直接复用该实例,并且回调onNewIntent方法。可以从他们的hashcode中可以看出这是同一个实例。因此我们可以理解为:SingleInstance模式启动的Activity在系统中具有全局唯一性。

综上所述,纯属个人愚见,也建议读者动手实践,动手才是王道,欢迎大家一起探讨![这里写图片描述]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值