Android系統(tǒng)服務(wù)(一)解析ActivityManagerService(AMS)


相關(guān)文章
Android系統(tǒng)啟動(dòng)流程系列
Android應(yīng)用進(jìn)程系列
Android深入四大組件系列

前言

此前在Android系統(tǒng)啟動(dòng)流程、應(yīng)用進(jìn)程以及深入四大組件這三個(gè)系列文章中,都提及到了AMS,但都沒(méi)有系統(tǒng)的來(lái)講解它,本文就以AMS為主來(lái)進(jìn)行講解,其中會(huì)有一些知識(shí)點(diǎn)與這些系列文章有所重合,這里會(huì)盡量做到詳盡講解。閱讀此文章前,最好閱讀相關(guān)文章中列出的系列文章,否則我不敢保證這篇文章你能看的懂。

1.概述

AMS是系統(tǒng)的引導(dǎo)服務(wù),應(yīng)用進(jìn)程的啟動(dòng)、切換和調(diào)度、四大組件的啟動(dòng)和管理都需要AMS的支持。從這里可以看出AMS的功能會(huì)十分的繁多,當(dāng)然它并不是一個(gè)類承擔(dān)這個(gè)重責(zé),它有一些關(guān)聯(lián)類,這在文章后面會(huì)講到。AMS的涉及的知識(shí)點(diǎn)非常多,這篇文章主要會(huì)講解AMS的以下幾個(gè)知識(shí)點(diǎn):

  • AMS的啟動(dòng)流程。
  • AMS與進(jìn)程啟動(dòng)。
  • AMS家族。

2.AMS的啟動(dòng)流程

AMS的啟動(dòng)是在SyetemServer進(jìn)程中啟動(dòng)的,在Android系統(tǒng)啟動(dòng)流程(三)解析SyetemServer進(jìn)程啟動(dòng)過(guò)程這篇文章中提及過(guò),這里從SyetemServer的main方法開(kāi)始講起:
frameworks/base/services/java/com/android/server/SystemServer.java

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

main方法中只調(diào)用了SystemServer的run方法,如下所示。
frameworks/base/services/java/com/android/server/SystemServer.java

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處加載了動(dòng)態(tài)庫(kù)libandroid_servers.so。接下來(lái)在注釋2處創(chuàng)建SystemServiceManager,它會(huì)對(duì)系統(tǒng)的服務(wù)進(jìn)行創(chuàng)建、啟動(dòng)和生命周期管理。在注釋3中的startBootstrapServices方法中用SystemServiceManager啟動(dòng)了ActivityManagerService、PowerManagerService、PackageManagerService等服務(wù)。在注釋4處的startCoreServices方法中則啟動(dòng)了BatteryService、UsageStatsService和WebViewUpdateService。注釋5處的startOtherServices方法中啟動(dòng)了CameraService、AlarmManagerService、VrManagerService等服務(wù)。這些服務(wù)的父類均為SystemService。從注釋3、4、5的方法可以看出,官方把系統(tǒng)服務(wù)分為了三種類型,分別是引導(dǎo)服務(wù)、核心服務(wù)和其他服務(wù),其中其他服務(wù)是一些非緊要和一些不需要立即啟動(dòng)的服務(wù)。系統(tǒng)服務(wù)總共大約有80多個(gè),我們主要來(lái)查看引導(dǎo)服務(wù)AMS是如何啟動(dòng)的,注釋3處的startBootstrapServices方法如下所示。

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

   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處調(diào)用了SystemServiceManager的startService方法,方法的參數(shù)是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方法傳入的參數(shù)是Lifecycle.class,Lifecycle繼承自SystemService。首先,通過(guò)反射來(lái)創(chuàng)建Lifecycle實(shí)例,注釋1處得到傳進(jìn)來(lái)的Lifecycle的構(gòu)造器constructor,在注釋2處調(diào)用constructor的newInstance方法來(lái)創(chuàng)建Lifecycle類型的service對(duì)象。接著在注釋3處將剛創(chuàng)建的service添加到ArrayList類型的mServices對(duì)象中來(lái)完成注冊(cè)。最后在注釋4處調(diào)用service的onStart方法來(lái)啟動(dòng)service,并返回該service。Lifecycle是AMS的內(nèi)部類,代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

   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
        }
    }

上面的代碼結(jié)合SystemServiceManager的startService方法來(lái)分析,當(dāng)通過(guò)反射來(lái)創(chuàng)建Lifecycle實(shí)例時(shí),會(huì)調(diào)用注釋1處的方法創(chuàng)建AMS實(shí)例,當(dāng)調(diào)用Lifecycle類型的service的onStart方法時(shí),實(shí)際上是調(diào)用了注釋2處AMS的start方法。在SystemServer的startBootstrapServices方法的注釋1處,調(diào)用了如下代碼:

 mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();

我們知道SystemServiceManager的startService方法最終會(huì)返回Lifecycle類型的對(duì)象,緊接著又調(diào)用了Lifecycle的getService方法,這個(gè)方法會(huì)返回AMS類型的mService對(duì)象,見(jiàn)注釋3處,這樣AMS實(shí)例就會(huì)被創(chuàng)建并且返回。

3.AMS與進(jìn)程啟動(dòng)

Android系統(tǒng)啟動(dòng)流程(二)解析Zygote進(jìn)程啟動(dòng)過(guò)程這篇文章中,我提到了Zygote的Java框架層中,會(huì)創(chuàng)建一個(gè)Server端的Socket,這個(gè)Socket用來(lái)等待AMS來(lái)請(qǐng)求Zygote來(lái)創(chuàng)建新的應(yīng)用程序進(jìn)程。要啟動(dòng)一個(gè)應(yīng)用程序,首先要保證這個(gè)應(yīng)用程序所需要的應(yīng)用程序進(jìn)程已經(jīng)被啟動(dòng)。AMS在啟動(dòng)應(yīng)用程序時(shí)會(huì)檢查這個(gè)應(yīng)用程序需要的應(yīng)用程序進(jìn)程是否存在,不存在就會(huì)請(qǐng)求Zygote進(jìn)程將需要的應(yīng)用程序進(jìn)程啟動(dòng)。Service的啟動(dòng)過(guò)程中會(huì)調(diào)用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用來(lái)描述Service的android:process屬性。注釋2處將procName和Service的uid傳入到AMS的getProcessRecordLocked方法中,來(lái)查詢是否存在一個(gè)與Service對(duì)應(yīng)的ProcessRecord類型的對(duì)象app,ProcessRecord主要用來(lái)記錄運(yùn)行的應(yīng)用程序進(jìn)程的信息。注釋5處判斷Service對(duì)應(yīng)的app為null則說(shuō)明用來(lái)運(yùn)行Service的應(yīng)用程序進(jìn)程不存在,則調(diào)用注釋6處的AMS的startProcessLocked方法來(lái)創(chuàng)建對(duì)應(yīng)的應(yīng)用程序進(jìn)程,
具體的過(guò)程請(qǐng)查看Android應(yīng)用程序進(jìn)程啟動(dòng)過(guò)程(前篇)。

4.AMS家族

ActivityManager是一個(gè)和AMS相關(guān)聯(lián)的類,它主要對(duì)運(yùn)行中的Activity進(jìn)行管理,這些管理工作并不是由ActivityManager來(lái)處理的,而是交由AMS來(lái)處理,ActivityManager中的方法會(huì)通過(guò)ActivityManagerNative(以后簡(jiǎn)稱AMN)的getDefault方法來(lái)得到ActivityManagerProxy(以后簡(jiǎn)稱AMP),通過(guò)AMP就可以和AMN進(jìn)行通信,而AMN是一個(gè)抽象類,它會(huì)將功能交由它的子類AMS來(lái)處理,因此,AMP就是AMS的代理類。AMS作為系統(tǒng)核心服務(wù),很多API是不會(huì)暴露給ActivityManager的,因此ActivityManager并不算是AMS家族一份子。
為了講解AMS家族,這里拿Activity的啟動(dòng)過(guò)程舉例,Activity的啟動(dòng)過(guò)程中會(huì)調(diào)用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方法中會(huì)調(diào)用AMN的getDefault來(lái)獲取AMS的代理類AMP。接著調(diào)用了AMP的startActivity方法,先來(lái)查看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方法調(diào)用了gDefault的get方法,我們接著往下看,gDefault 是一個(gè)Singleton類。注釋1處得到名為”activity”的Service引用,也就是IBinder類型的AMS的引用。接著在注釋2處將它封裝成AMP類型對(duì)象,并將它保存到gDefault中,此后調(diào)用AMN的getDefault方法就會(huì)直接獲得AMS的代理對(duì)象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的構(gòu)造方法如下所示。

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

class ActivityManagerProxy implements IActivityManager
{
    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }
...
 }

AMP的構(gòu)造方法中將AMS的引用賦值給變量mRemote ,這樣在AMP中就可以使用AMS了。
其中IActivityManager是一個(gè)接口,AMN和AMP都實(shí)現(xiàn)了這個(gè)接口,用于實(shí)現(xiàn)代理模式和Binder通信。
再回到Instrumentation的execStartActivity方法,來(lái)查看AMP的startActivity方法,AMP是AMN的內(nèi)部類,代碼如下所示。
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;
   }

首先會(huì)將傳入的參數(shù)寫(xiě)入到Parcel類型的data中。在注釋1處,通過(guò)IBinder類型對(duì)象mRemote(AMS的引用)向服務(wù)端的AMS發(fā)送一個(gè)START_ACTIVITY_TRANSACTION類型的進(jìn)程間通信請(qǐng)求。那么服務(wù)端AMS就會(huì)從Binder線程池中讀取我們客戶端發(fā)來(lái)的數(shù)據(jù),最終會(huì)調(diào)用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中會(huì)調(diào)用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方法會(huì)最后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方法最后會(huì)return ActivityStarter的startActivityMayWait方法,這一調(diào)用過(guò)程已經(jīng)脫離了本節(jié)要講的AMS家族,因此這里不做介紹了,具體的調(diào)用過(guò)程可以查看Android深入四大組件(一)應(yīng)用程序啟動(dòng)過(guò)程(后篇)這篇文章。

在Activity的啟動(dòng)過(guò)程中提到了AMP、AMN和AMS,它們共同組成了AMS家族的主要部分,如下圖所示。

AMP是AMN的內(nèi)部類,它們都實(shí)現(xiàn)了IActivityManager接口,這樣它們就可以實(shí)現(xiàn)代理模式,具體來(lái)講是遠(yuǎn)程代理:AMP和AMN是運(yùn)行在兩個(gè)進(jìn)程的,AMP是Client端,AMN則是Server端,而Server端中具體的功能都是由AMN的子類AMS來(lái)實(shí)現(xiàn)的,因此,AMP就是AMS在Client端的代理類。AMN又實(shí)現(xiàn)了Binder類,這樣AMP可以和AMS就可以通過(guò)Binder來(lái)進(jìn)行進(jìn)程間通信。

ActivityManager通過(guò)AMN的getDefault方法得到AMP,通過(guò)AMP就可以和AMN進(jìn)行通信,也就是間接的與AMS進(jìn)行通信。除了ActivityManager,其他想要與AMS進(jìn)行通信的類都需要通過(guò)AMP,如下圖所示。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容