天天看點

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

之前寫過Service的啟動過程,相對來說Activity的啟動過程比Service的啟動過程更為複雜,其一Activity的生命周期方法比Service多,其二Activity具有啟動模式和傳回棧。寫本文的目的在于更清晰的梳理Activity的啟動過程,加強自己的内功修煉,部落格粉絲日益增多,力在以最簡單的方式讓大家了解,跟大家一起學習。

Activity的啟動過程計劃用三篇部落格來寫;

  • 第一篇(本文),側重Binder視角或者從程序這方面,對Activity啟動先從整體有個把握,代碼少,理論多。
  • 第二篇,深入源碼,分析Launcher程序向SystemServer程序發起startActivity請求,SystemServer程序在向zygote程序發起請求,最後孵化出應用程序的這一過程。
  • 第三篇:深入源碼,由Zygote程序孵化的應用程序是如何啟動Activity的。

一、Binder的基本了解

Activity的啟動有多次IPC過程,是以Binder屬于預備知識,幫助我們更好了解系統的C/S的這種架構模式,我看過幾篇文章還不錯,推薦給大家。

  • 簡單說Binder(1)

    作者寫的很清晰,相信看過之後,在JAVA的層面上,立馬明白Binder的IPC過程是怎麼回事。

  • 可能是講解Binder機制最好的文章

    加強了解一下

  • Android Bander設計與實作 - 設計篇

    最經典的不多說了,值得反複看

  • Android源碼解析RPC系列(一)—Binder原理

    這一篇是我去年寫的,都不好意思一塊貼出來了。

二、Activity啟動的雙向IPC過程

一般Android各個應用程序的啟動都以這樣一條路線,init程序 –> Zygote程序 –> SystemServer程序 –>各種應用程序

  • Init程序:Linux的根程序,Android系統是基于Linux系統的,是以可以算作是整個android作業系統的第一個程序;
  • Zygote程序是所有應用程序的父程序,所有的應用程序都是它孵化出來的;
  • SystemServer程序含有一些核心的服務,比如ActivityManagerService,PackageManagerService,WindowManagerService等;
  • 各種應用程序:啟動自己編寫的用戶端應用時,有自己的虛拟機與運作環境。

由此可知應用的第一個Activity的啟動是多個程序互相配合的結果,多個程序互相配合就少不了使用Binder進行IPC了,現在看一次IPC調用的過程是怎樣的。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

上圖大概說明了一次IPC的過程,或許你現在對裡面各個類還不是很清楚,沒關系,大緻了解一下

ActivityManagerService(下文簡稱AMS),AMS是Android中最核心的服務,實作了ActivityManager,主要負責系統中四大元件的啟動、切換、排程及應用程序的管理和排程等工作,AMS提供了一個ArrayList mHistory來管理所有的Activity,Activity在AMS中的形式是ActivityRecord,Task在AMS中的形式為TaskRecord,程序在AMS中的管理形式為ProcessRecord,它在Android中特别重要。

ActivityManagerNative(下文簡稱AMN):由于AMS是系統核心服務在SystemServer程序裡面,很多API不能直接開放供用戶端使用,是以需要通過IPC的方式,具體是這樣的,ActivityManager類内部調用AMN的getDefault函數得到一個ActivityManagerProxy對象,通過它可與AMS通信。

ActivityManagerProxy(下文簡稱AMP):AMP是AMS在用戶端程序的一個代理,通過AMP裡面的方法請求AMS。

Instrumentation:Instrumentaion是一個工具類,一個大管家。當它被啟用時,系統先建立它,再通過它來建立其他元件。另外,系統群組件之間的互動也将通過Instrumentation來傳遞,這樣,Instrumentation就能監測系統和這些元件的互動情況了。在實際使用中,我們可以建立Instrumentation的派生類來進行相應的處理。Android中Junit的使用到了Intrstrumentation。關于它更詳細的了解,戳我。

OK,現在我們知道,Activity是如何向AMS發出startActivity這個請求了,這意味着Activity可以與AMS進行通信,但是AMS卻不能與Activity通信,Binder是單向的,是以在Activity送出請求之後,AMS需要通知Activity發生狀态改變,要做到這一點,自然就在AMS到Activity這個過程建立一個Binder,如下。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

大緻過程就是,SystemServer程序在收到請求後,再通過IPC向應用程序發送scheduleLaunchActivity請求,應用程序的binder線程(ApplicationThread)在收到請求後,通過handler向主線程發送LAUNCH_ACTIVITY消息,主線程在收到Message後,建立目标Activity,并回調Activity.onCreate()等方法。

對上面的了解不是太明白,在看下面這張圖,簡單多了,AMS到Activity這個過程建立了一個Binder,Activity到AMS這個過程也建立了一個Binder,這就能互相通信了。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

上圖就是Activity與AMS之間的雙向Binder連接配接,(備注:這個就是了解Activity啟動流程的指南針,不記住這個,複雜的啟動流程會讓你暈頭轉向)。Activity用IActivityManager提供的API向AMS提出執行某個動作的請求(本例中是啟動RemoteService),AMS通過IApplicationThread提供的API來控制Activity所在的應用程式,這些API包括schedulePauseActivity()、scheduleStopActivity()等。

IActivityManager接口定義的API,啟動四大元件的等多種請求都在裡面。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

IApplicationThread接口定義的API,一看就比IActivityManager高逼格一點,IActivityManager好多方法是start開頭,表示去AMS請求,IApplicationThread以schedule開頭,表示對Activity進行排程。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握

分析到這裡,我們不知不覺間忽略了兩個問題,那就是啟動Activity至少需要兩個前提,第一是,應用程序存在,第二AMS已經初始化完畢。在調用startActivity方法時候,如果我們的應用程序不存在,Activity能啟動嗎,當然是不能的,比如點選桌面圖示的時候,這個時候需要先建立程序。關于Zygote孵化應用程序,這個暫時不說,先看看AMS服務注冊。

三、AMS服務注冊

先忽略 Activity調用ActivityManagerService啟動應用,直接從SystemServer的main方法說起。

SystemServer.java

  /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
           

run方法中,調用了startBootstrapServices。

private void startBootstrapServices() {

        ......
        //啟動AMS服務
        Installer installer = mSystemServiceManager.startService(Installer.class);

        //請注意這裡參數是Lifecycle,因為AMS是在Lifecycle裡面new出來的
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

        mActivityManagerService.initPowerManagement();

         ......
        mActivityManagerService.setSystemProcess();
      ......
}
           
public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
        }
        return startService(serviceClass);
    }
           

繼續

public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            // 1、建立服務
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
              // 如果傳進來的是ActivityManagerService.Lifecycle對象,那麼ActivityManagerService就能被建立
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            }
            // 2、注冊服務
            mServices.add(service);

            // 3、啟動服務
            try {
                service.onStart();
            } catch (RuntimeException ex) {
                throw new RuntimeException("Failed to start service " + name
                        + ": onStart threw an exception", ex);
            }
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
           
ActivityManagerService.java

   public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
          //ActivityManagerService被new出來了
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
          //  啟動
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }
           
private void start() {
        Process.removeAllProcessGroups();
        mProcessCpuThread.start();

        mBatteryStatsService.publish(mContext);
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }
           

回到 startBootstrapServices裡面調用的 mActivityManagerService.setSystemProcess();

public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            ......


       // 設定application info LoadedApkinfo 有關 framework-res.apk
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS);
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

        //給SystemServer程序建立ProcessRecord,adj值,就是将SystemServer程序加入到AMS程序管理機制中,跟應用程序一緻
        synchronized (this) {
            ProcessRecord app = newProcessRecordLocked(info, info.processName, false, );
            app.persistent = true;
            app.pid = MY_PID;
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
            }
            updateLruProcessLocked(app, false, null);
            updateOomAdjLocked();
  }
           

ServiceManager這裡面注冊了很多的服務,可通過dumpsys <服務名>指令檢視。比如檢視CPU資訊指令dumpsys cpuinfo,檢視graphics資訊指令dumpsys gfxinfo。在Android中所有的核心服務,并不是直接給上層使用,都先交給ServiceManager管理,上層使用的時候可以從ServiceManager擷取,ServiceManager相當于一個路由作用。現在來看一張經典的圖。其中注冊服務,擷取服務以及使用服務,每一次都是一個完整的Binder IPC過程,可見了解Binder是多麼的重要啊。關于AMS啟動得深入了解,請戳我。

Android源碼解析四大元件系列(二)---Activity啟動過程的總體把握
  • 注冊服務:首先AMS注冊到ServiceManager。AMS所在程序(SystemServer)是用戶端,ServiceManager是服務端。
  • 擷取服務:Client程序使用AMS前,須先向ServiceManager中擷取AMS的代理類AMP。該過程。AMP所在程序(應用程序)是用戶端,ServiceManager是服務端。
  • 使用服務: app程序根據得到的代理類AMP,便可以直接與AMS所在程序互動。該過程,AMP所在程序(應用程序)是用戶端,AMS所在程序(SystemServer)是服務端。

OK ,本文終于寫完了,翻看源碼,查閱資料,畫圖花了兩天時間,最後回顧一下,本文解釋了雙向Binder是如何建立的?這個是最重要的部分,其次AMS作為管理Android系統元件的核心服務,AMS是如何注冊的?(在SystemServer執行run()方法的時候被建立,并運作在獨立的程序中)。OK,see you。

·

Please accept mybest wishes for your happiness and success

參考連結:

http://www.cloudchou.com/android/post-788.html

[Android源碼解析之(八)–>Zygote程序啟動流程]

(http://blog.csdn.net/qq_23547831/article/details/51104873)

[深入了解Android卷二 全文-第六章]深入了解ActivityManagerService

深入AndroidFramework源碼内部剖析Service的啟動過程

Android系統啟動-SystemServer