Service組件的啓動機制深入學習


一、通過startService方式啓動

1、ContextWrapper#startService:

/** @path: \frameworks\base\core\java\android\content\ContextWrapper.java **/
@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}
mBase的類型是ContextImpl;


2、ContextImpl#StartService:

/** @path: \frameworks\base\core\java\android\app\ContextImpl.java**/
@Override
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, mUser);
}

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        // 驗證Intent是否合法
        validateServiceIntent(service);
        service.prepareToLeaveProcess();
        // t通過AMS來啓動Service
        ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
        // 處理返回的Service組件信息是否合法
        if (cn != null) {
            if (cn.getPackageName().equals("!")) {
                throw new SecurityException(
                        "Not allowed to start service " + service
                                + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
                throw new SecurityException(
                        "Unable to start service " + service
                                + ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
        return null;
    }
}
上面代碼中主要步驟是ActivityManagerNative.getDefault().startService;從Activity組件啓動過程及ActivityManagerService(AMS)(一)》中知道ActivityManagerNative.getDefault()的類型其實是AMS的代理:ActivityManagerProxy;則下面調用ActivityManagerProxy的startService函數;(ActivityManagerProxy是ActivityManagerNative的內部類);


3、ActivityManagerProxy#startService:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public ComponentName startService(IApplicationThread caller, Intent service,
                                      String resolvedType, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeInt(userId);
        // IPC消息傳遞,消息類型:START_SERVICE_TRANSACTION
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }
}
類似於Activity的啓動過程,最終仍是通過AMS發送START_SERVICE_TRANSACTION消息來startService;

ActivityManagerService處理START_SERVICE_TRANSACTION類型消息的函數爲startService。


4、ActivityManagerService#startService:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
                                  String resolvedType, int userId) {
    enforceNotIsolatedCaller("startService");
    // 不處理包含文件描述符的Intent消息
    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    synchronized(this) {
        
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        // @value final ActiveServices mServices;
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}
上面的處理邏輯較爲簡單,首先避免處理包含有文件描述符的Intent,以保證系統安全;然後調用ActiveServices的startServiceLocked函數;


5、ActiveServices#startServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
ComponentName startServiceLocked(IApplicationThread caller,
                                 Intent service, String resolvedType,
                                 int callingPid, int callingUid, int userId) {
    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        .....
        callerFg = callerApp.setSchedGroup != android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }

    // 注意該函數,該函數會將Service信心封裝成ServiceLookupResult類型返回
    ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, userId, true, callerFg);
    if (res == null) {
        return null;
    }
    if (res.record == null) {
        return new ComponentName("!", res.permission != null ? res.permission : "private to package");
    }

    // 類似於ActivityRecord,ServiceRecord是記錄Service相關信息的數據結構
    ServiceRecord r = res.record;

    if (!mAm.getUserManagerLocked().exists(r.userId)) {
        return null;
    }

    .......
    // 調用此函數繼續啓動Service
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
    注意retrieveServiceLocked函數,該函數會在AMS中查找是否已經存在一個與參數service(Intent)對應的ServiceRecord對象(類似於ActivityRecord,ServiceRecord是用來描述Service組件的數據結構);如果不存在,則AMS會到PMS中獲取與參數service相對應的一個Service組件信息,將組件信息封裝成ServiceRecord,進而再封裝成ServiceLookupResult對象返回。

獲取到serviceRecord後,繼續調用startServiceInnerLocked來啓動Service。


6、ActiveServices#retrieveServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private ServiceLookupResult retrieveServiceLocked(Intent service,
                                                  String resolvedType, int callingPid, int callingUid, int userId,
                                                  boolean createIfNeeded, boolean callingFromFg) {
    ServiceRecord r = null;

    userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
            false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);

    // 根據userId獲取ServiceMap,根據名稱很容易知道這裏是保存Service組價的地方
    ServiceMap smap = getServiceMap(userId);
    // 查找smap中是否已經存在了service對應的Service組件信息
    final ComponentName comp = service.getComponent();
    if (comp != null) {
        // 根據組件名查找
        r = smap.mServicesByName.get(comp);
    }
    if (r == null) {
        // 根據Intent Filter查找 (可以看到分別對應顯式、隱式兩種啓動方式)
        Intent.FilterComparison filter = new Intent.FilterComparison(service);
        r = smap.mServicesByIntent.get(filter);
    }

    // 如果爲查找到
    if (r == null) {
        try {
            // AMS會繼續往PMS中去獲取相對應的Service組件信息(manifest中定義的service)
            ResolveInfo rInfo =
                    AppGlobals.getPackageManager().resolveService(
                            service, resolvedType,
                            ActivityManagerService.STOCK_PM_FLAGS, userId);
            ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
            if (sInfo == null) {
                Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
                        ": not found");
                return null;
            }
            ComponentName name = new ComponentName(sInfo.applicationInfo.packageName, sInfo.name);
            if (userId > 0) {
                if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                        sInfo.name, sInfo.flags)
                        && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                    userId = 0;
                    smap = getServiceMap(0);
                }
                sInfo = new ServiceInfo(sInfo);
                sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
            }
            r = smap.mServicesByName.get(name);
            if (r == null && createIfNeeded) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(service.cloneFilter());
                ServiceRestarter res = new ServiceRestarter();
                BatteryStatsImpl.Uid.Pkg.Serv ss = null;
                BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
                synchronized (stats) {
                    ss = stats.getServiceStatsLocked(
                            sInfo.applicationInfo.uid, sInfo.packageName,
                            sInfo.name);
                }
                // 將查找到的信息組裝成ServiceRecord類型
                r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                res.setService(r);
                smap.mServicesByName.put(name, r); // 可以看到分別按照name和filter的形式添加到smap中
                smap.mServicesByIntent.put(filter, r);

                // Make sure this component isn't in the pending list.
                for (int i=mPendingServices.size()-1; i>=0; i--) {
                    ServiceRecord pr = mPendingServices.get(i);
                    if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                            && pr.name.equals(name)) {
                        mPendingServices.remove(i);
                    }
                }
            }
        } catch (RemoteException ex) {
            // pm is in same process, this will never happen.
        }
    }
    // 創建好ServiceRecord後,將其封裝成ServiceLookupResult類型返回
    if (r != null) {
        if (mAm.checkComponentPermission(r.permission,
                callingPid, callingUid, r.appInfo.uid, r.exported)
                != PackageManager.PERMISSION_GRANTED) {
            if (!r.exported) {
                return new ServiceLookupResult(null, "not exported from uid "
                        + r.appInfo.uid);
            }
            return new ServiceLookupResult(null, r.permission);
        }
        if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                resolvedType, r.appInfo)) {
            return null;
        }
        return new ServiceLookupResult(r, null);
    }
    return null;
}


 7、ActiveService#startServiceInnerLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
                                      ServiceRecord r, boolean callerFg, boolean addToStarting) {
    ProcessStats.ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
    }
    r.callStart = false;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked();
    }
    // 使用bringUpServiceLocked來啓動ServiceRecord對應的Service組件
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    if (error != null) {
        // 看到前面判斷中錯誤組件名"!"與”!!“
        return new ComponentName("!!", error);
    }

    if (r.startRequested && addToStarting) {
        boolean first = smap.mStartingBackground.size() == 0;
        smap.mStartingBackground.add(r);
        r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
        if (first) {
            smap.rescheduleDelayedStarts();
        }
    } else if (callerFg) {
        smap.ensureNotStartingBackground(r);
    }

    return r.name;
}
    函數繼續調用bringUpServiceLocked方法來啓動或得到的ServiceRecord所描述的Service組件信息;


8、ActiveServices#bringUpServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) {

    // ====== Service組件啓動之前的一系列準備工作 ======//
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }

    if (!whileRestarting && r.restartDelay > 0) {
        // If waiting for a restart, then do nothing.
        return null;
    }
    // 當前正在啓動Service,所以該ServiceRecord無需再是restart狀態
    if (mRestartingServices.remove(r)) {
        clearRestartingIfNeededLocked(r);
    }

    // Make sure this service is no longer considered delayed, we are starting it now.
    if (r.delayed) {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }

    // 確定Service的持有者已經started,否則將不允許開啓
    if (mAm.mStartedUsers.get(r.userId) == null) {
        String msg = "Unable to launch app "
                + r.appInfo.packageName + "/"
                + r.appInfo.uid + " for service "
                + r.intent.getIntent() + ": user " + r.userId + " is stopped";
        bringDownServiceLocked(r);
        return msg;
    }

    // Service正在啓動,其PMS不可被關閉
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
    }

    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;

    // 獲取ServiceRecord對應的Service組件中的android:process屬性(manifest中所描述的)
    final String procName = r.processName;
    ProcessRecord app;

    if (!isolated) {
        // 判斷Service組件對應的process是否已經存在,已經存在表示該應用程序進程已經啓動
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        // 如果存在,則調用realStartServiceLocked方法去開啓Service
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (RemoteException e) {
            }
        }
    } else {
        app = r.isolatedProc;
    }

    // 如果Service對應進程不存在,並未啓動,則調用startProcessLocked方法去開啓
    if (app == null) {
        // @value final ActivityManagerService mAm;
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = "Unable to launch app "
                    + r.appInfo.packageName + "/"
                    + r.appInfo.uid + " for service "
                    + r.intent.getIntent() + ": process is bad";
            bringDownServiceLocked(r);
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }

    // 將ServiceRecord保存到mPendingServices變量中
    if (!mPendingServices.contains(r)) {
        mPendingServices.add(r);
    }

    if (r.delayedStop) {
        // Oh and hey we've already been asked to stop!
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r);
        }
    }

    return null;
}
    該函數前期做了一系列Service組件啓動前的處理工作;後面首先獲取Service組件的process屬性,即在manifest中定義的android:process屬性,獲知service組件運行的進程信息;通過getProcessRecordLocked函數,獲知process屬性對應的進程是否已經運行;如果已經運行,則app不爲null,直接調用realStartServiceLocked方法去開啓Service;如果Service所要求的進程並未運行,在要調用ActivityManagerService的startProcessLocked方法去開啓 。

    這裏分情況討論,先討論複雜情況,即Service要求在另一個進程中去開啓,即process對應的進程未開啓;

(一)應用進程未創建情況:

1、ActivityManagerService#startProcessLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
final ProcessRecord startProcessLocked(String processName,
                                       ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                                       String hostingType, ComponentName hostingName, boolean allowWhileBooting,
                                       boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                       boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
                                       boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
                                       String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ProcessRecord app;
    if (!isolated) {
        // 首先檢查請求創建的進程是否已經存在
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
    } else {
        // If this is an isolated process, it can't re-use an existing process.
        app = null;
    }
    .......

    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;

    .......

    // 如果應用並未創建
    if (app == null) {
        // 根據processName及uid來創建Progress,newProcessRecordLocked所做的工作就是new ProcessRecord(stats, info, proc, uid);
        // 即創建一個ProcessRecord對象
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            return null;
        }
        app.crashHandler = crashHandler;
        // ProcessRecord創建完畢後,會將該對象添加到mProcessNames中,便於下次查找
        mProcessNames.put(processName, app.uid, app);
        if (isolated) {
            mIsolatedProcesses.put(app.uid, app);
        }
    } else {
        // If this is a new package in the process, add the package to the list
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
    }

    .......
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    return (app.pid != 0) ? app : null;
}
上面代碼中的主要工作是首先判斷該processName對應的進程是否已經創建且存在,

如果未存在,則調用newProcessRecordLocked方法去出創建;newProcessRecordLocked方法的主要工作就是new ProcessRecord(stats, info, proc, uid);即創建一個ProcessRecord對象;

新創建的ProcessRecord對象添加到mProcessNames中,便於下次查找。

最後調用另一個重載版本startProcessLocked方法去創建進程。


2、ActivityManagerService#startProcessLocked:   

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
private final void startProcessLocked(ProcessRecord app, String hostingType,
                                      String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    .......

    try {
        // ==== 獲得待啓動的進程的UID與GID ====== //
        int uid = app.uid;
        int[] gids = null;
        .......
        // 調用Process的start方法來啓動新進程
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        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);
        .......
        // 保存Process信息
        app.setPid(startResult.pid);
        app.usingWrapper = startResult.usingWrapper;
        app.removed = false;
        app.killed = false;
        app.killedByAm = false;
        synchronized (mPidsSelfLocked) {
            // 將新啓動的進程,以PID爲鍵值將進程信息保存
            this.mPidsSelfLocked.put(startResult.pid, app);
            if (isActivityProcess) {
                /** 這裏的啓動邏輯是AMS的Handler在PROC_START_TIMEOUT時間後,發送PROC_START_TIMEOUT_MSG消息
                 *  新的應用進程必須在時間內完成啓動工作,並向AMS發送啓動完成消息,進而AMS可在該進程中啓動Service等組件
                 *  否則,AMS將會認爲進程啓動超時*/
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        }
    } catch (RuntimeException e) {
        ......
    }
}
     主要調用Process的start方法來啓動新進程,並將新進程的信息保存到mPidsSelfLocked變量中;

    然後AMS中的Handler會延時發送一個消息,這裏的啓動邏輯是AMS的Handler在PROC_START_TIMEOUT時間後,發送PROC_START_TIMEOUT_MSG消息;新的應用進程必須在時間內完成啓動工作,並向AMS發送啓動完成消息,進而AMS可在該進程中啓動Service等組件;否則,AMS將會認爲進程啓動超時。

    來看一下Process的啓動過程;進程都是由Zygote創建的,這裏來看一下進程的入口函數,start調用時傳遞的參數:entryPoint = "android.app.ActivityThread",可以看到這裏的入口class是ActivityThread。具體的啓動函數爲ActivityThread的main方法;


3、ActivityThread#main:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
public static void main(String[] args) {

    ......
    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    // 關鍵在於attach
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    Looper.loop();
}
    創建主線程的Looper,handler消息傳遞循環環境;然後調用attach方法向AMS發送一個啓動完成通知。


4、ActivityThread#attach:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    // 普通進程的情況
    if (!system) {
        .......
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                UserHandle.myUserId());
        // @value final ApplicationThread mAppThread = new ApplicationThread();
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // 獲得AMS代理ActivityManagerProxy
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            // 將ApplicationThread對象傳遞給AMS,AMS就是通過它來與應用進程進行通信的
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
        .....
    } else {
        // 如果是系統進程則直接進行下面創建操作
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            // 創建mInstrumentation及ContextImpl
            mInstrumentation = new Instrumentation();
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            // 創建Application
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            // 調用Application的onCreate
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }
    .....
}
    這裏會創建一個ApplicationThread對象mAppThread,mAppThread將會通過attachApplication傳遞給AMS,AMS通過其來與應用進程進行通信。在attachApplication後,創建Application,調用Application的onCreate,開始生命週期。


5、ActivityManagerNative#ActivityManagerProxy#attachApplication: 

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
}
    傳遞進來的參數就是mAppThread(ApplicationThread),傳遞給AMS,消息類型爲ATTAH_APPLICATION_TRANSACTION;

由Binder通知機制,來看ActivityManagerNative對IPC消息的處理:


6、ActivityManagerNative#onTransact:

/** @path:  \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 ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
    }
}
可以看到其具體的處理函數交給子類實現的attachApplication去實現;ActivityManagerService是ActivityManagerNative的子類。


7、ActivityManagerService#attachApplication:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}
繼續來看attachAplicationLocked函數;


8、ActivityManagerService#attachAplicationLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
@Override
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
    ProcessRecord app;
    // 獲取新創建的應用進程
    if (pid != MY_PID && pid >= 0) { // 應用進程的pid
        synchronized (mPidsSelfLocked) {
            // 在第二步中,mPidsSelfLocked保存了新創建的Process的相關記錄數據結構ProcessRecord,這裏通過get獲取pid對應的ProcessRecord
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }
    ......

    final String processName = app.processName;
    .......
    boolean badApp = false;
    boolean didSomething = false;

    // 可以看到下面根據需要開啓Activity和Service
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }

    // 查看該進程是否有需要啓動的Services
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }

    // Check if a next-broadcast receiver is in this process...
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            // If the app died trying to launch the receiver we declare it 'bad'
            badApp = true;
        }
    }

    // Check whether the next backup agent is in this process...
    if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
        ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        } catch (Exception e) {
            badApp = true;
        }
    }

    .......

    return true;
}
由前面第二步知,將新創建的進程保存到ActivityManagerService中的mPidsSelfLocked變量中,現在根據關鍵字PID,將其獲取出來,保存到變量app中。

Service組件的相關啓動工作在mServices.attachApplicationLocked(app, processName);中完成,該函數會檢查是否有Service組件需要進行啓動。mServices的類型爲ActiveServices;


9、ActiveServices#attachApplicationLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException {
    boolean didSomething = false;
    // 之前在第八步中ActiveServices#bringUpServiceLocked,將待啓動的ServiceRecord保存到mPendingServices變量中
    if (mPendingServices.size() > 0) { // 這裏判斷mPendingServices的大小,確定是否有待啓動的Service
        ServiceRecord sr = null;
        try {
            // 遍歷所有待啓動Service
            for (int i=0; i<mPendingServices.size(); i++) {
                sr = mPendingServices.get(i);
                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName))) {
                    continue;
                }

                mPendingServices.remove(i);
                i--;
                proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                        mAm.mProcessStats);
                // 如方法名所示,這裏是真正開啓Service的地方
                realStartServiceLocked(sr, proc, sr.createdFromFg);
                didSomething = true;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception in new application when starting service "
                    + sr.shortName, e);
            throw e;
        }
    }
    // Also, if there are any services that are waiting to restart and
    // would run in this process, now is a good time to start them.  It would
    // be weird to bring up the process but arbitrarily not let the services
    // run at this point just because their restart time hasn't come up.
    if (mRestartingServices.size() > 0) {
        ServiceRecord sr = null;
        for (int i=0; i<mRestartingServices.size(); i++) {
            sr = mRestartingServices.get(i);
            if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                    || !processName.equals(sr.processName))) {
                continue;
            }
            mAm.mHandler.removeCallbacks(sr.restarter);
            mAm.mHandler.post(sr.restarter);
        }
    }
    return didSomething;
}
這裏的邏輯其實較爲簡單,前面一中第8步ActiveServices#bringUpServiceLocked,將待啓動的ServiceRecord保存到mPendingServices變量中。這裏僅需要判斷mPendingServices是否爲空,如果不爲空,則表示有待啓動的Service,然後遍歷mPendingServices,對所有的Service(記錄Service組件信息的爲ServiceRecord)執行realStartServiceLocked,正如方法名所言,這裏是真正開啓Service的地方。


10、ActiveServices#realStartServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final void realStartServiceLocked(ServiceRecord r,
                                          ProcessRecord app, boolean execInFg) throws RemoteException {
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    // 將待啓動的ServiceRecord添加到該進程ProcessRecord的services變量中
    app.services.add(r);
    bumpServiceExecutingLocked(r, execInFg, "create");

    boolean created = false;
    try {
        ........
        // @value IApplicationThread thread;
        // 繼續調用IApplicationThread的scheduleCreateService函數
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
    } finally {
        if (!created) {
            app.services.remove(r);
            r.app = null;
            // 啓動未成功進行重啓
            scheduleServiceRestartLocked(r, false);
            return;
        }
    }
    .......
}
   首先將需要啓動的Service組件(ServiceRecord)添加到其所在進程(ProcessRecord)的services變量中;接下來調用app.thread.scheduleCreateService來繼續啓動Service組件;app.thread是ProcessRecord的IApplicationThread變量,調用IApplicationThread的scheduleCreateService方法;

    這裏的app.thread是第一部分第3步ActivityManagerProxy#startService方法中的通過Binder傳進去的caller.asBinder(),即Binder代理對象;而caller的實際運行類型爲:mMainThread.getApplicationThread()獲取的(mMainThread的類型爲ActivityThread)。

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
final ApplicationThread mAppThread = new ApplicationThread();
public ApplicationThread getApplicationThread()
{
    return mAppThread;
}
可以看到caller的實際類型爲ApplicationThread;

而ApplicationThread繼承ApplicationThreadNative:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative
調用asBinder返回的是ApplicationThreadNative自己本身實例;

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public IBinder asBinder()
{
    return this;
}
而在Binder Service代理對象進行處理時:

/** @path: \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_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            // app
            hust.testlearn.View.IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            int userId = data.readInt();
            // 這裏調用子類ActivityManagerProxy的startService方法,見第一部分,步驟四
            ComponentName cn = startService(app, service, resolvedType, userId);
            reply.writeNoException();
            ComponentName.writeToParcel(cn, reply);
            return true;
        }
    }
}
可以看到第一部分第4步startService中傳進來的參數app(即caller)的實際類型由 ApplicationThreadNative.asInterface(b);來獲得。

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative
/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    static public hust.testlearn.View.IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        hust.testlearn.View.IApplicationThread in =
                (hust.testlearn.View.IApplicationThread) obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ApplicationThreadProxy(obj);
    }
}
可以看到app的實際類型爲ApplicationThreadProxy;

即前面app.thread的實際類型爲ApplicationThreadProxy,下面接着調用ApplicationThreadProxy的scheduleCreateService方法;


11、ApplicationThreadProxy#scheduleCreateService:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public final void scheduleCreateService(IBinder token, ServiceInfo info,
                                        CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(hust.testlearn.View.IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    // 依舊是個IPC,傳遞消息爲SCHEDULE_CREATE_SERVICE_TRANSACTION
    mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}
發送一個 SCHEDULE_CREATE_SERVICE_TRANSACTION IPC通信請求。具體來看其處理函數:


12ApplicationThreadNative#onTransact:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
            data.enforceInterface(hust.testlearn.View.IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            int processState = data.readInt();
            // 調用子類的scheduleCreateService,其子類爲ApplicationThread
            scheduleCreateService(token, info, compatInfo, processState);
            return true;
        }
    }
}
    會繼續調用子類的ApplicationThread中的scheduleCreateService進行處理。


13、ApplicationThread中#scheduleCreateService:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative {
    final H mH = new H();
    public final void scheduleCreateService(IBinder token,
                                            ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
        updateProcessState(processState, false);
        CreateServiceData s = new CreateServiceData();
        s.token = token;
        s.info = info;
        s.compatInfo = compatInfo;

        // 可以看到和啓動Activity過程非常相似
        sendMessage(H.CREATE_SERVICE, s);
    }

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
}
可以看到具體的處理邏輯和開啓Activity非常相似,通過Handler發送一個 CREATE_SERVICE消息,等待處理;


14、H:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class H extends Handler {
    public static final int CREATE_SERVICE          = 114;
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case CREATE_SERVICE:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
                handleCreateService((CreateServiceData) msg.obj);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
        }
    }

    private void handleCreateService(CreateServiceData data) {

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            // 獲得類加載器
            ClassLoader cl = packageInfo.getClassLoader();
            // 通過類加載器創建一個Service實例
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
        }

        try {
            // 創建Context環境
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            // 將service attach到Application中
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            // 調用Service的onCreate開始生命週期
            service.onCreate();
            // 將Service組件添加到mServices變量中
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
        }
    }
}
具體的處理邏輯爲通過類加載器創建該組件名對應的Service實例對象,然後創建Context環境與Application(因爲該環境下假設是進程未創建的情況),將Service attcah到該環境中;創建完成Service組件之後,調用onCreate,開始Service的生命週期;則整個Service的啓動過程完成; 


(二)應用進程已經創建情況:
回到前面第一部分末,來看進程已經創建情況,可以看到如果進程已經創建,則會直接跳過前面步驟,跳到第二部分的第10步ActiveServices#realStartServiceLocked直接向下執行;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章