Kitkat Activity、Task、Application和Process

来源:互联网 发布:排水沟标高计算软件 编辑:程序博客网 时间:2024/06/01 10:25
名词解释:

ActivityManagerService,简称AmS:系统重要服务,管理四大组件,有一个特别重要就是管理所有的java层进程,包括它自己运行在的系统进程。

 

一.Task到底是什么?

Task可以理解为实现一个功能,负责管理所有用到的Activity的栈。

 

组件可以跨应用被调用,但是一个组件必须运行在组件所在的Aplication的进程中。

 

由于android强化了组件概念,弱化了Aplication的概念,所以在android程序开发中,A应用的A组件想要使用拍照或录像的功能就可以不用去针对Camera类进行开发,直接调用系统自带的摄像头应用(称其B应用)中的组件(称其B组件)就可以了,但是这就引发了一个新问题,A组件跑在A应用中,B组件跑在B应用中,自然都不在同一个进程中,那么从B组件中返回的时候,如何实现正确返回到A组件呢?Task 就是来负责实现这个功能的,它是从用户角度来理解应用而建立的一个抽象概念。

 

在AmS中就是使用TaskRecord类来管理所有运行在该Task中的Activity。TaskRecord成员变量mActivities就是保存所有运行在该Task中的ActivityRecord实例。

 

二.谁负责管理Activity?

1.真正调度一个Application中的所有Activity的是ActivityThread类,每个进程只有一个ActivityThread。换句话说,每个ActivityThread调度该进程中所有应用的Activity。

2. AmS管理整个系统中所有Activity的是系统服务,整个系统只有一个。

3.在KitKat中Ams通过ActivityStack管理一个Activity栈中所有的Activity,使用ActivityStackSupervisor来管理所有的ActivityStack。而AmS只需要管理好ActivityStackSupervisor单实例就可以了。

4.真正启动Activity的类是Instrument,每个进程只有一个Instrument实例。

5.TaskRecord也负责管理Activity。

 

有以上内容可以知道,在AmS使用了一个层级结构来管理Activity。

 

三、Activity、Application与Process的关系

首先来了解下启动一个Activity与Application和Process的关系。

在所属应用第一个Activity启动之前会启动该Activity所在Application的进程,因为一个Activity只能运行在所属Application所在的进程中。

 

结论:

1.      一般情况下每个Application都是运行在一个进程中,特列:Application中的Service在AndroidManifest.xml中对android:process属性赋值,进而是Service运行在其他进程中。例如:

android:process="android.process.media"

 

2.      每个进程可以运行多个Application,拥有相同的sharedUserId,例如系统应用:“音乐”,“下载内容”就都是运行在android.media进程中的,例如:

android:sharedUserId="android.media"

 

3.      一个java进程等价于一个java虚拟机。

 

四、Activity和Task的关系

 

影响Activity启动关键点大致有三个因素:

因素一:Activity注册信息中的launchMode;

因素二:启动Activity时Intent中的launchFlags;

因素三:Activity注册信息中的 taskAffinity、allowTaskReparenting、clearTaskOnLaunch、alwaysRetainTaskState、finishOnTaskLaunch等信息。

 

通常情况下,我们只需要针对第一个因素进行合理设置就能满足我们应用开发的需求了。

 

launchMode的四种方式:

 

launchMode的设置方法是在apk的AndroidManifest.xml文件中针对每一个Activity的 android:launchMode属性进行设置的方式,共有四种模式可以设置,分别是standard、singleTop、singleTask、singleInstance。

 

standard

standard是默认模式,即假设用户在AndroidManifest.xm中对Activity不指定 android:launchMode的情况下,缺省启动模式即为standard。在启动一个以standard为launchMode的Activity时,AmS只是简单的创建一个新的Activity实例,设置它的TaskId则与启动它的Activity相同,并将其放到相应TaskRecord的mActivities的栈顶。这种是最常见的使用方式。

 

singleTop

启动一个以singleTop为lauchMode的Activity时,Ams会查询当前获得焦点的ActivityStack中的所有Task: 假如在Task顶端正是要启动的Activity实例,那么Ams就不会重新启动一个Activity实例,而是调用Task栈顶的该Activity实例的OnNewIntent()函数;假如在Task栈顶不是该Activity的实例,然后将Activity的实例压入调用者所在的Task,这种方式主要用于避免自调自过程中,产生多个实例的情况。

 

singleTask

启动一个以singleTask为lauchMode的Activity时,Ams会查询所有的Task:如果某个Task内有一个该Activity的实例,那么这个Activity实例一定是该Task的根Activity,这个是由于singleTask特性决定的,销毁位于该Task中,该Activity实例之上的其他Activity实例,实际上就是销毁该Task中其他的Activity实例。如果所有的Task中都没有Activity的实例,那么新建一个Task,该Activity成为该Task的根Activity,该Task可以运行其他的Activity,这个特性是与singleInstance的区别。

 

singleInstance

启动一个以singleInstance为launchmode的Activity时,假如某个Task中已经有一个该类实例,那么调用其onNewIntent()函数,自启动;否则就会创建一个新的Task,该Task中只有该Activity运行,不会再有其他Activity进入该Task。这也是与singleTask的唯一区别。


总结:

声明为SingleInstance和SingleTask的Activity只能是一个栈的栈底,而且SingleInstance与SingleTask的区别也仅仅是SingleInstance自己独占一个Task,而SingleTask只是一个Task的栈底,该Task还可以有其他的Activity。所以本图中画得不是特别正确,也只是示意一下。对SingleTop而言,如果task中目标Activity在task的栈顶,那么直接调用该Activity的onNewIntent()方法,自启动;如果目标Activity不在task的栈顶,那么就新建一个Activity对象压入调用者所在的栈顶。


0 0
原创粉丝点击