Android解析ActivityManagerService(一)AMS啓動流程和AMS家族

相關文章
Android系統啓動流程系列
Android應用進程系列
Android深刻四大組件系列html

前言

此前在Android系統啓動流程、應用進程以及深刻四大組件這三個系列文章中,都說起到了AMS,但都沒有系統的來說解它,本文就以AMS爲主來進行講解,其中會有一些知識點與這些系列文章有所重合,這裏會儘可能作到詳盡講解。閱讀此文章前,最好閱讀相關文章中列出的系列文章,不然我不敢保證這篇文章你能看的懂。java

1.概述

AMS是系統的引導服務,應用進程的啓動、切換和調度、四大組件的啓動和管理都須要AMS的支持。從這裏能夠看出AMS的功能會十分的繁多,固然它並非一個類承擔這個重責,它有一些關聯類,這在文章後面會講到。AMS的涉及的知識點很是多,這篇文章主要會講解AMS的如下幾個知識點:android

  • AMS的啓動流程。
  • AMS與進程啓動。
  • AMS家族。

2.AMS的啓動流程

AMS的啓動是在SyetemServer進程中啓動的,在Android系統啓動流程(三)解析SyetemServer進程啓動過程這篇文章中說起過,這裏從SyetemServer的main方法開始講起:
frameworks/base/services/java/com/android/server/SystemServer.java微信

public static void main(String[] args) {
       new SystemServer().run();
   }複製代碼

main方法中只調用了SystemServer的run方法,以下所示。
frameworks/base/services/java/com/android/server/SystemServer.javaapp

private void run() {
       ...
           System.loadLibrary("android_servers");//1
       ...
           mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
           LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
       ...    
        try {
           Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
           startBootstrapServices();//3
           startCoreServices();//4
           startOtherServices();//5
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
       }
       ...
   }複製代碼

在註釋1處加載了動態庫libandroid_servers.so。接下來在註釋2處建立SystemServiceManager,它會對系統的服務進行建立、啓動和生命週期管理。在註釋3中的startBootstrapServices方法中用SystemServiceManager啓動了ActivityManagerService、PowerManagerService、PackageManagerService等服務。在註釋4處的startCoreServices方法中則啓動了BatteryService、UsageStatsService和WebViewUpdateService。註釋5處的startOtherServices方法中啓動了CameraService、AlarmManagerService、VrManagerService等服務。這些服務的父類均爲SystemService。從註釋三、四、5的方法能夠看出,官方把系統服務分爲了三種類型,分別是引導服務、核心服務和其餘服務,其中其餘服務是一些非緊要和一些不須要當即啓動的服務。系統服務總共大約有80多個,咱們主要來查看引導服務AMS是如何啓動的,註釋3處的startBootstrapServices方法以下所示。框架

frameworks/base/services/java/com/android/server/SystemServer.javaide

private void startBootstrapServices() {
        Installer installer = mSystemServiceManager.startService(Installer.class);
        // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();//1
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
      ...
    }複製代碼

在註釋1處調用了SystemServiceManager的startService方法,方法的參數是ActivityManagerService.Lifecycle.class:
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java源碼分析

@SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
           ...
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);//1
                service = constructor.newInstance(mContext);//2
            } catch (InstantiationException ex) {
              ...
            }
            // Register it.
            mServices.add(service);//3
            // Start it.
            try {
                service.onStart();//4
            } 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);
        }
    }複製代碼

startService方法傳入的參數是Lifecycle.class,Lifecycle繼承自SystemService。首先,經過反射來建立Lifecycle實例,註釋1處獲得傳進來的Lifecycle的構造器constructor,在註釋2處調用constructor的newInstance方法來建立Lifecycle類型的service對象。接着在註釋3處將剛建立的service添加到ArrayList類型的mServices對象中來完成註冊。最後在註釋4處調用service的onStart方法來啓動service,並返回該service。Lifecycle是AMS的內部類,代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javaui

public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;
        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);//1
        }
        @Override
        public void onStart() {
            mService.start();//2
        }
        public ActivityManagerService getService() {
            return mService;//3
        }
    }複製代碼

上面的代碼結合SystemServiceManager的startService方法來分析,當經過反射來建立Lifecycle實例時,會調用註釋1處的方法建立AMS實例,當調用Lifecycle類型的service的onStart方法時,其實是調用了註釋2處AMS的start方法。在SystemServer的startBootstrapServices方法的註釋1處,調用了以下代碼:spa

mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();複製代碼

咱們知道SystemServiceManager的startService方法最終會返回Lifecycle類型的對象,緊接着又調用了Lifecycle的getService方法,這個方法會返回AMS類型的mService對象,見註釋3處,這樣AMS實例就會被建立而且返回。

3.AMS與進程啓動

Android系統啓動流程(二)解析Zygote進程啓動過程這篇文章中,我提到了Zygote的Java框架層中,會建立一個Server端的Socket,這個Socket用來等待AMS來請求Zygote來建立新的應用程序進程。要啓動一個應用程序,首先要保證這個應用程序所須要的應用程序進程已經被啓動。AMS在啓動應用程序時會檢查這個應用程序須要的應用程序進程是否存在,不存在就會請求Zygote進程將須要的應用程序進程啓動。Service的啓動過程當中會調用ActiveServices的bringUpServiceLocked方法,以下所示。
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException {
  ...
  final String procName = r.processName;//1
  ProcessRecord app;
  if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//2
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {//3
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode,
                    mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);//4
                    return null;
                } catch (TransactionTooLargeException e) {
              ...
            }
        } else {
            app = r.isolatedProc;
        }
 if (app == null && !permissionsReviewRequired) {//5
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {//6
              ...
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
 ...     
}複製代碼

在註釋1處獲得ServiceRecord的processName的值賦值給procName ,其中ServiceRecord用來描述Service的android:process屬性。註釋2處將procName和Service的uid傳入到AMS的getProcessRecordLocked方法中,來查詢是否存在一個與Service對應的ProcessRecord類型的對象app,ProcessRecord主要用來記錄運行的應用程序進程的信息。註釋5處判斷Service對應的app爲null則說明用來運行Service的應用程序進程不存在,則調用註釋6處的AMS的startProcessLocked方法來建立對應的應用程序進程,
具體的過程請查看Android應用程序進程啓動過程(前篇)

4.AMS家族

ActivityManager是一個和AMS相關聯的類,它主要對運行中的Activity進行管理,這些管理工做並非由ActivityManager來處理的,而是交由AMS來處理,ActivityManager中的方法會經過ActivityManagerNative(之後簡稱AMN)的getDefault方法來獲得ActivityManagerProxy(之後簡稱AMP),經過AMP就能夠和AMN進行通訊,而AMN是一個抽象類,它會將功能交由它的子類AMS來處理,所以,AMP就是AMS的代理類。AMS做爲系統核心服務,不少API是不會暴露給ActivityManager的,所以ActivityManager並不算是AMS家族一份子。
爲了講解AMS家族,這裏拿Activity的啓動過程舉例,Activity的啓動過程當中會調用Instrumentation的execStartActivity方法,以下所示。
frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }複製代碼

execStartActivity方法中會調用AMN的getDefault來獲取AMS的代理類AMP。接着調用了AMP的startActivity方法,先來查看AMN的getDefault方法作了什麼,以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//1
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//2
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }+
    };
}複製代碼

getDefault方法調用了gDefault的get方法,咱們接着往下看,gDefault 是一個Singleton類。註釋1處獲得名爲」activity」的Service引用,也就是IBinder類型的AMS的引用。接着在註釋2處將它封裝成AMP類型對象,並將它保存到gDefault中,此後調用AMN的getDefault方法就會直接得到AMS的代理對象AMP。註釋2處的asInterface方法以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    return new ActivityManagerProxy(obj);
}複製代碼

asInterface方法的主要做用就是將IBinder類型的AMS引用封裝成AMP,AMP的構造方法以下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager {
    public ActivityManagerProxy(IBinder remote) {
        mRemote = remote;
    }
...
 }複製代碼

AMP的構造方法中將AMS的引用賦值給變量mRemote ,這樣在AMP中就可使用AMS了。
其中IActivityManager是一個接口,AMN和AMP都實現了這個接口,用於實現代理模式和Binder通訊。
再回到Instrumentation的execStartActivity方法,來查看AMP的startActivity方法,AMP是AMN的內部類,代碼以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
     ...
       data.writeInt(requestCode);
       data.writeInt(startFlags);
     ...
       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
       reply.readException();+
       int result = reply.readInt();
       reply.recycle();
       data.recycle();
       return result;
   }複製代碼

首先會將傳入的參數寫入到Parcel類型的data中。在註釋1處,經過IBinder類型對象mRemote(AMS的引用)向服務端的AMS發送一個START_ACTIVITY_TRANSACTION類型的進程間通訊請求。那麼服務端AMS就會從Binder線程池中讀取咱們客戶端發來的數據,最終會調用AMN的onTransact方法,以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

@Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
       switch (code) {
       case START_ACTIVITY_TRANSACTION:
       {
       ...
           int result = startActivity(app, callingPackage, intent, resolvedType,
                   resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
           reply.writeNoException();
           reply.writeInt(result);
           return true;
       }
   }複製代碼

onTransact中會調用AMS的startActivity方法,以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
 public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
             resultWho, requestCode, startFlags, profilerInfo, bOptions,
             UserHandle.getCallingUserId());
 }複製代碼

startActivity方法會最後return startActivityAsUser方法,以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
     enforceNotIsolatedCaller("startActivity");
     userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
             userId, false, ALLOW_FULL_ONLY, "startActivity", null);
     return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
             profilerInfo, null, null, bOptions, false, userId, null, null);
  }複製代碼

startActivityAsUser方法最後會return ActivityStarter的startActivityMayWait方法,這一調用過程已經脫離了本節要講的AMS家族,所以這裏不作介紹了,具體的調用過程能夠查看Android深刻四大組件(一)應用程序啓動過程(後篇)這篇文章。

在Activity的啓動過程當中提到了AMP、AMN和AMS,它們共同組成了AMS家族的主要部分,以下圖所示。

AMP是AMN的內部類,它們都實現了IActivityManager接口,這樣它們就能夠實現代理模式,具體來說是遠程代理:AMP和AMN是運行在兩個進程的,AMP是Client端,AMN則是Server端,而Server端中具體的功能都是由AMN的子類AMS來實現的,所以,AMP就是AMS在Client端的代理類。AMN又實現了Binder類,這樣AMP能夠和AMS就能夠經過Binder來進行進程間通訊。

ActivityManager經過AMN的getDefault方法獲得AMP,經過AMP就能夠和AMN進行通訊,也就是間接的與AMS進行通訊。除了ActivityManager,其餘想要與AMS進行通訊的類都須要經過AMP,以下圖所示。

參考資料
[深刻理解Android卷二 全文-第六章]深刻理解ActivityManagerService
Framework源碼分析(一):ActivityManagerService
ActivityManager與Proxy模式的運用


歡迎關注個人微信公衆號,第一時間得到博客更新提醒,以及更多成體系的Android相關原創技術乾貨。
掃一掃下方二維碼或者長按識別二維碼,便可關注。

相關文章
相關標籤/搜索