ActivityManagerService流程

Activity启动流程

目的:

  • 理清activity的生命周期管理与AMS之间的关系

一、理清activity的生命周期管理与AMS之间的关系

1、Launcher通知AMS启动某个activity:

Launcher中:应用程序中开启一个activity通过startActivitySafely()---->startActivity(),如果是程序内部启动那么直接调用Activity中的startActivity(),被启动的activity的参数包含在intent中,intent中的参数来自于.xml
文件,--->startActivityForResult()----> mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options),其中Instrumentation是用来监控应用程序与系统之间的交互,其中mMainThread是ActivityThread类的实例,.getApplicationThread()用于获取内部的ApplicationThread的Binder对象(此处有疑问??);----->ActivityManagerNative.getDefault()
.startActivity(), .getDefault()通过ServerManager获取AMS的代理对象"activity",代码如下:

//ActivityManagerNative.java
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity"); //获取代理对象
            if (false) {
               Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
           return am;
        }
};

接着调用他的方法startActivity()通知AMS启动相应的Activity,这里已经是binder通讯了。

startActivitySafely()    <-----------------Launcher中,如果是在Launcher中点击,从这一步开始
        |
startActivity()          <-----------------Activity中,如果是程序中调用,从这一步开始
    |
startActivityForResult() <-----------------Activity中
    |
mInstrumentation.execStartActivity()  <----------Instrumentation中
    |
ActivityManagerNative.getDefault().startActivity()<----------AMS的proxy
    |
    ...binder...    Launcher--->AMS: Launcher请求启动activity
    |
startActivity()    ---------->通知AMS的Stub中startActivity(),即ActivityManagerService.java中的

至此Launcher中暂时结束!即Launcher进程会------>请求AMS启动一个activity,具体是哪一个activity,看intent

2、AMS保存将要启动的mainactivity,并且AMS处理Launcher向AMS发送的binder消息:START_ACTIVITY_TRANSACTION

startActivity()                     ------->AMS   
    |
startActivityAsUser()               ------->AMS
    |
mStackSupervisor.startActivityMayWait() ------->ActivityStackSupervisor.java 
    |
startActivityLocked()           ------->ActivityStackSupervisor.java      
    |
startActivityUncheckedLocked()
    |
resumeTopActivitiesLocked(targetStack, null, options)  ----->ActivityStack.java
    |
startPausingLocked()                ----->ActivityStack.java
    |
prev.app.thread.schedulePauseActivity() ----->ActivityStack.java   Proxy
    |
    ...binder...    AMS--->Launcher: AMS请求Launcher Pause
    |
schedulePauseActivity()         ------>ActivityThread.java   Stub  

//ActivityThread.java
public final void schedulePauseActivity(IBinder token, boolean finished,
          boolean userLeaving, int configChanges, boolean dontReport) {
     sendMessage(
             finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
             token,
             (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
             configChanges);
}
    1. mStackSupervisor.startActivityMayWait()中还会用binder和PMS通讯,解析intent中的界面内容,以便显示
    1. mStackSupervisor是ActivityStackSupervisor的成员变量,用于描述Activity组件堆栈(疑问???)
    1. startPausingLocked()中又会涉及到一个binder通讯,这个是AMS向Launcher组件所在的应用程序进程发送通讯SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:需要Pause掉Launcher了
      至此AMS暂时结束,即AMS向Launcher组件所在的应用程序进程发送了SCHEDULE_PAUSE_ACTIVITY_TRANSACTION进程间通讯请求,请求内容是告诉Launcher组件Pause吧。当然其中会有一些列的异步超时处理。

3、Launcher收到Pause请求后的动作,并回复AMS(通过AMS的proxy)

schedulePauseActivity()         ------>ActivityThread.java   Stub  
    |
sendMessage()               ------>ActivityThread.java  果然这里是消息处理机制实现
    |
handleMessage(Message msg)      ------>ActivityThread.java  
    |   
handlePauseActivity()
    |
performPauseActivity(token, finished, r.isPreHoneycomb());   ------>ActivityThread.java  
ActivityManagerNative.getDefault().activityPaused(token)     ------>ActivityThread.java  AMS proxy
    |
    ...binder...    Launcher--->AMS : Launcher告知AMS,Launcher已经Pause
    |
activityPaused(token)           ------>AMS Stub
    1. activityPaused()获取AMS的proxy,用于回复AMS:告诉AMS,Launcher已经进入Pause状态了;AMS你可以继续启动Activity了。
    1. performPauseActivity()--->mInstrumentation.callActivityOnPause(r.activity)--->activity.performPause() ---> onPause() 这应该就是与APP继承的 onPause()一致的。

疑问:

  • 至此Launcher已经Paused了,并通过binder进程间通讯发送了ACTIVITY_PAUSED_TRANSACTION告知AMS。

4、AMS中处理Launcher发来的Paused通讯请求,并做相应处理

activityPaused(token)           ------>AMS Stub
    |
activityPausedLocked()          ------>ActivityStack.java
    |
completePauseLocked(true)
    |
finishCurrentActivityLocked()
    |
resumeTopActivityLocked()
    |
resumeTopActivityInnerLocked()
    |
startSpecificActivityLocked()       ------->ActivityStackSupervisor.java
    |
startProcessLocked()            ------->AMS
    |
startProcessLocked()            ------->重载的函数,  AMS (如果进程不在的话)
//AMS  startProcessLocked()
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
        app.processName, uid, uid, gids, debugFlags, mountExternal,
        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
        app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
    |
try {
    return startViaZygote(processClass, niceName, uid, gid, gids,
        debugFlags, mountExternal, targetSdkVersion, seInfo,
        abi, instructionSet, appDataDir, zygoteArgs);
} 
    |
zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
    |
通知zygote孵化出新的虚拟机应用程序,并返回PID给AMS,新的应用程序启动起来之后就会进入ActivityThread的main方法中。

至此,AMS就调用Process类创建了一个新的应用程序。并且,该进程的入口函数为main函数,接下来就是新的应用程序进程的工作了。

5、新的应用程序启动之后,会向AMS发送一个启动完成的进程间通讯。

main()                  ------->ActivityThread.java
    |
Looper.prepareMainLooper()  ------->创建消息循环队列,是当前应用进程进入消息循环队列中
ActivityThread thread = new ActivityThread()          创建一个ActivityThread对象  
attach(boolean system)      ------->ActivityThread.java
    |
final IActivityManager mgr = ActivityManagerNative.getDefault();//获取AMS的proxy
mgr.attachApplication(mAppThread)       ----->AMS proxy,调用IActivityManager的接口通讯函数
    |
    ...binder...    ActivityThread--->AMS: APP进程告知AMS启动进程完成
    |
attachApplication(IApplicationThread thread)    ----->AMS Stub
    |
Looper.loop()   

至此,新的应用程序进程通过调用,thread.attach(false)调用attach()函数来向AMS的proxy发送一个进程间通讯回复ATTACH_APPLICATION_TRANSACTION:告诉AMS新的应用程序已经启动完成。

6、 AMS将2步中保存的MainActivity信息,发送给第4步中创建的新应用程序,,以便它可以将MainActivity启动起来

attachApplication(IApplicationThread thread)    ----->AMS Stub
    |
attachApplicationLocked(IApplicationThread thread, int pid) ----->AMS 
    |
attachApplicationLocked(ProcessRecord app)  ----->ActivityStackSupervisor.java  重载
    |
realStartActivityLocked(hr, app, true, true)    ----->ActivityStackSupervisor.java      
    |
app.thread.scheduleLaunchActivity()     ----->ActivityThread proxy
    |
    ...binder...    AMS--->ActivityThread: AMS将MainActivity信息发送新进程
    |
scheduleLaunchActivity()            ----->ActivityThread Stub

至此,AMS向ActivityThread发送进程间通讯SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION

7、应用程序中执行最后工作

scheduleLaunchActivity()            ----->ActivityThread Stub
    |
sendMessage(H.LAUNCH_ACTIVITY, r)       
    |
handleMessage(Message msg)
    |
handleLaunchActivity(r, null)
    |
Activity a = performLaunchActivity(r, customIntent)
    |
mInstrumentation.callActivityOnCreate(activity, r.state)  ------->Instrumentation.java
    |
activity.performCreate(icicle)
    |
onCreate(icicle)        ------>Activity.java
    |
protected void onCreate(@Nullable Bundle savedInstanceState) 

APP中继承的OnCreate()就被调用起来了,最后一步将Activity对象activity启动起来了

注意:

1、mainActivity组件是由Launcher组件启动的,Launcher组件又是通过AMS来启动mainActivity的,因此会涉及到三个进程之间的binder通讯
2、AMS启动是和PMS一样,都在systemServer进程中启动起来的,startBootstrapServices()函数中。
3、还得理清楚ActivityManagerService.java,ActivityManagerNative.java,IActivityManager.java之间的关系

  1. ActivityManagerService.java毋庸置疑肯定是Activity栈管理实现
  2. ActivityManagerNative.java根据代码看,应该是BnXXXX和BpXXXX,也就是binder本地和代理,ActivityManagerService里面才是真正的物理实现。所有的通讯都是通过ActivityManagerNative处理的
  3. IActivityManager.java当然是接口类,ActivityManagerNative实现IActivityManager。

总结,问题:

    1. 目前只看到onCreate() 被调用的地方,其他的生命周期onRestart(),onStart(), onResume() ,onPause() ,onStop() ,onDestroy() 是怎么被AMS调用转换的???
      解:都在ActivityThread(UI主线程)管理的,当发生生命周期变换时,最终都会call到Activity.java中去,而这个文件正是APP中继承的Activity。
      应用进程启动时会先创建Application对象,并执行Application对象的生命周期方法,然后才启动应用的组件。
      ActivityThread ---> performPauseActivity() ---> callActivityOnPause()--->performPause()--->onPause()
      ActivityThread ---> performResumeActivity() --> performResume()--->onResume()
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);   // launch之后紧接着调用ResumeActivity

            if (!r.activity.mFinished && r.startsNotResumed) {
                performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        }
    }

...

    1. ActivityStack堆栈组件???
      解:mStackSupervisor是ActivityStackSupervisor的成员变量,用于描述Activity组件堆栈
      在startActivityLocked方法里,对传过来的参数做一些校验,然后创建ActivityRecord对象,再调用startActivityUncheckedLocked方法启动Activity。
      startActivityUncheckedLocked方法负责调度ActivityRecord和Task,理解该方法是理解Actvity启动模式的关键。
    1. Activity与Window对应关系?
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容