Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> startService啟動過程分析詳細教程

startService啟動過程分析詳細教程

編輯:關於Android編程

基於Android 6.0的源碼剖析, 分析android Service啟動流程中ActivityManagerService所扮演的角色

/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
/frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
/frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/core/java/android/app/IActivityManager.java
/frameworks/base/core/java/android/app/ActivityManagerNative.java (內含ActivityManagerProxy類)
/frameworks/base/core/java/android/app/ActivityManager.java

/frameworks/base/core/java/android/app/IApplicationThread.java
/frameworks/base/core/java/android/app/ApplicationThreadNative.java (內含ApplicationThreadProxy類)
/frameworks/base/core/java/android/app/ActivityThread.java (內含ApplicationThread類)

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

一、概述

看過前面介紹Binder系列文章,相信對Binder架構有了較深地理解。在Android系統啟動-開篇中講述了Binder的地位是非常之重要,整個Java framework的提供ActivityManagerService、PackageManagerService等服務都是基於Binder架構來通信的,另外 handle消息機制在進程內的通信使用非常多。本文將開啟對ActivityManagerService的分析。

ActivityManagerService是Android的Java framework的服務框架最重要的服務之一。對於Andorid的Activity、Service、Broadcast、ContentProvider四劍客的管理,包含其生命周期都是通過ActivityManagerService來完成的。對於這四劍客的介紹,此處先略過,後續博主會針對這4劍客分別闡述。

1.1 類圖

下面先看看ActivityManagerService相關的類圖:

activity_manager_classes

單單就一個ActivityManagerService.java文件就代碼超過2萬行,我們需要需要一個線,再結合binder的知識,來把我們想要了解的東西串起來,那麼本文將從App啟動的視角來分析ActivityManagerService。

1.2 流程圖

在app中啟動一個service,就一行語句搞定,

startService(); //或 binderService()

該過程如下:

start_service

當App通過調用Android API方法startService()或binderService()來生成並啟動服務的過程,主要是由ActivityManagerService來完成的。

  1. ActivityManagerService通過Socket通信方式向Zygote進程請求生成(fork)用於承載服務的進程ActivityThread。此處講述啟動遠程服務的過程,即服務運行於單獨的進程中,對於運行本地服務則不需要啟動服務的過程。ActivityThread是應用程序的主線程;
  2. Zygote通過fork的方法,將zygote進程復制生成新的進程,並將ActivityThread相關的資源加載到新進程;
  3. ActivityManagerService向新生成的ActivityThread進程,通過Binder方式發送生成服務的請求;
  4. ActivityThread啟動運行服務,這便於服務啟動的簡易過程,真正流程遠比這服務;

啟動服務的流程圖:

點擊查看大圖

Seq_start_service

圖中涉及的首字母縮寫:

  • AMP:ActivityManagerProxy
  • AMN:ActivityManagerNative
  • AMS:ActivityManagerService
  • AT:ApplicationThread
  • ATP:ApplicationThreadProxy
  • ATN:ApplicationThreadNative

接下來,我們正式從代碼角度來分析服務啟動的過程。首先在我們應用程序的Activity類的調用startService()方法,該方法調用【流程1】的方法。

二、源碼分析

1. CW.startService

[-> ContextWrapper.java]

public class ContextWrapper extends Context {
    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service); //其中mBase為ContextImpl對象 【見流程2】
    }
}

2. CI.startService

[-> ContextImpl.java]

class ContextImpl extends Context {
    @Override
    public ComponentName startService(Intent service) {
        //當system進程調用此方法時輸出warn信息,system進程建立調用startServiceAsUser方法
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser); //【見流程3】
    }

3. CI.startServiceCommon

[-> ContextImpl.java]

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        //檢驗service,當service為空則throw異常
        validateServiceIntent(service);
        service.prepareToLeaveProcess();
        // 調用ActivityManagerNative類 【見流程3.1 以及流程4】
        ComponentName cn = ActivityManagerNative.getDefault().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());
        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) {
        throw new RuntimeException("Failure from system", e);
    }
}

3.1 AMN.getDefault

[-> ActivityManagerNative.java]

static public IActivityManager getDefault() {
    return gDefault.get();
}

gDefault為Singleton類型對象,此次采用單例模式,mInstance為IActivityManager類的代理對象,即ActivityManagerProxy。

public abstract class Singleton<T> {
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                //首次調用create()來獲取AMP對象
                mInstance = create();
            }
            return mInstance;
        }
    }
}

再來看看create()的過程:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        //獲取名為"activity"的服務,服務都注冊到ServiceManager來統一管理
        IBinder b = ServiceManager.getService("activity");
        IActivityManager am = asInterface(b);
        return am;
    }
};

該方法返回的是ActivityManagerProxy對象,那麼下一步調用ActivityManagerProxy.startService()方法。

通過Binder通信過程中,提供了一個IActivityManager服務接口,ActivityManagerProxy類與ActivityManagerService類都實現了IActivityManager接口。ActivityManagerProxy作為binder通信的客戶端,ActivityManagerService作為binder通信的服務端,根據Binder系列文章,ActivityManagerProxy.startService()最終調用ActivityManagerService.startService(),整個流程圖如下:

Activity_Manager_Service

4. AMP.startService

該類位於文件ActivityManagerNative.java

public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, 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.writeString(callingPackage);
    data.writeInt(userId);
    //通過Binder 傳遞數據 【見流程5】
    mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    ComponentName res = ComponentName.readFromParcel(reply);
    data.recycle();
    reply.recycle();
    return res;
}

mRemote.transact()是binder通信的客戶端發起方法,經過binder驅動,最後回到binder服務端ActivityManagerNative的onTransact()方法。

5. AMN.onTransact

@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();
        //生成ApplicationThreadNative的代理對象,即ApplicationThreadProxy對象
        IApplicationThread app = ApplicationThreadNative.asInterface(b);
        Intent service = Intent.CREATOR.createFromParcel(data);
        String resolvedType = data.readString();
        String callingPackage = data.readString();
        int userId = data.readInt();
        //調用ActivityManagerService的startService()方法【見流程6】
        ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
        reply.writeNoException();
        ComponentName.writeToParcel(cn, reply);
        return true;
    }
}

在整個調用過程涉及兩個進程,不妨令startService的發起進程記為進程A,ServiceManagerService記為進程B;那麼進程A通過Binder機制(采用IActivityManager接口)向進程B發起請求服務,進程B則通過Binder機制(采用IApplicationThread接口)向進程A發起請求服務。也就是說進程A與進程B能相互間主動發起請求,進程通信。

這裡涉及IApplicationThread,那麼下面直接把其相關的類圖展示如下:

application_thread_classes

與IActivityManager的binder通信原理一樣,ApplicationThreadProxy作為binder通信的客戶端,ApplicationThreadNative作為Binder通信的服務端,其中ApplicationThread繼承ApplicationThreadNative類,覆寫其中的部分方法。

6. AMS.startService

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, String callingPackage, int userId)
        throws TransactionTooLargeException {
    //當調用者是孤立進程,則拋出異常。
    enforceNotIsolatedCaller("startService");

    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    if (callingPackage == null) {
        throw new IllegalArgumentException("callingPackage cannot be null");
    }
    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
            "startService: " + service + " type=" + resolvedType);

    synchronized(this) {
        final int callingPid = Binder.getCallingPid(); //調用者pid
        final int callingUid = Binder.getCallingUid(); //調用者uid
        final long origId = Binder.clearCallingIdentity();
        //此次的mServices為ActiveServices對象 【見流程7】
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, callingPackage, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

該方法參數說明:

  • caller:IApplicationThread類型,復雜處理
  • service:Intent類型,包含需要運行的service信息
  • resolvedType:String類型
  • callingPackage: String類型,調用該方法的package
  • userId: int類型,用戶的id

7. AS.startServiceLocked

[-> ActiveServices.java]

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, String callingPackage, int userId)
        throws TransactionTooLargeException {

    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        if (callerApp == null)
            throw new SecurityException(""); //拋出異常,此處省略異常字符串
        callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }
    //檢索服務信息
    ServiceLookupResult res =  retrieveServiceLocked(service, resolvedType, callingPackage,
                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");
    }
    ServiceRecord r = res.record;
    if (!mAm.getUserManagerLocked().exists(r.userId)) { //檢查是否存在啟動服務的user
        return null;
    }
    NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
            callingUid, r.packageName, service, service.getFlags(), null, r.userId);

    r.lastActivity = SystemClock.uptimeMillis();
    r.startRequested = true;
    r.delayedStop = false;
    r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
            service, neededGrants));
    final ServiceMap smap = getServiceMap(r.userId);
    boolean addToStarting = false;
    //對於非前台進程的調度
    if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
        ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
        if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
            if (r.delayed) {  //已計劃延遲啟動
                return r.name;
            }
            if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
                //當超出 同一時間允許後續啟動的最大服務數,則將該服務加入延遲啟動的隊列。
                smap.mDelayedStartList.add(r);
                r.delayed = true;
                return r.name;
            }
            addToStarting = true;
        } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
            //將新的服務加入到後台啟動隊列,該隊列也包含當前正在運行其他services或者receivers的進程
            addToStarting = true;
        }
    }
    //【見流程8】
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

8. AS.startServiceInnerLocked

[-> ActiveServices.java]

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    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(); //用於耗電統計,開啟運行的狀態
    }
    //【見流程9】
    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;
}

9. AS.bringUpServiceLocked

[-> ActiveServices.java]

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting) throws TransactionTooLargeException {
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
    if (!whileRestarting && r.restartDelay > 0) {
        return null; //等待延遲重啟的過程,則直接返回
    }

    // 啟動service前,把service從重啟服務隊列中移除
    if (mRestartingServices.remove(r)) {
        r.resetRestartCounter();
        clearRestartingIfNeededLocked(r);
    }
    //service正在啟動,將delayed設置為false
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }

    //確保擁有該服務的user已經啟動,否則停止;
    if (mAm.mStartedUsers.get(r.userId) == null) {
        String msg = "";
        bringDownServiceLocked(r);
        return msg;
    }
    //服務正在啟動,設置package停止狀態為false
    AppGlobals.getPackageManager().setPackageStoppedState(
            r.packageName, false, r.userId);

    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    ProcessRecord app;
    if (!isolated) {
        //根據進程名和uid,查詢ProcessRecord
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                // 啟動服務 【見流程12】
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (TransactionTooLargeException e) {
                throw e;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
            }
        }
    } else {
        app = r.isolatedProc;
    }

    //對於進程沒有啟動的情況
    if (app == null) {
        //啟動service所要運行的進程 【見流程10】
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = ""
            bringDownServiceLocked(r); // 進程啟動失敗
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }
    if (!mPendingServices.contains(r)) {
        mPendingServices.add(r);
    }
    if (r.delayedStop) {
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r); //停止服務
        }
    }
    return null;
}
  • 當start service的過程中,目標進程已經存在,則直接執行流程13來調用realStartServiceLocked;
  • 當目標進程不存在,則需要先創建進程,進入流程8,之後再調用realStartServiceLocked。

對於非前台進程調用而需要啟動的服務,如果已經有其他的後台服務正在啟動中,那麼我們可能希望延遲其啟動。這是用來避免啟動同時啟動過多的進程(非必須的)。

10. AMS.attachApplicationLocked

關於startProcessLocked的過程, 詳見 理解Android進程啟動之全過程,經過層層調用最後會調用到AMS.attachApplicationLocked過程.

[-> ActivityManagerService.java]

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    ...
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
            app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(mConfiguration), app.compat,
            getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked());

    ...
    if (!badApp) {
        try {
            //尋找所有需要在該進程中運行的服務 【見流程11】
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }
    ...
    return true;
}

11. AS.attachApplicationLocked

[-> ActiveServices.java]

boolean attachApplicationLocked(ProcessRecord proc, String processName)
        throws RemoteException {
    boolean didSomething = false;
    //啟動mPendingServices隊列中,等待在該進程啟動的服務
    if (mPendingServices.size() > 0) {
        ServiceRecord sr = null;
        try {
            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
                proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                        mAm.mProcessStats);
                // 啟動服務,即將進入服務的生命周期 【見流程10】
                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;
        }
    }
    // 對於正在等待重啟並需要運行在該進程的服務,現在是啟動它們的大好時機
    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;
}
  • 當需要創建新進程,則創建後經歷過attachApplicationLocked,則會再調用realStartServiceLocked();
  • 當不需要創建進程, 即在[流程9]中直接就進入了realStartServiceLocked();

12 AS.realStartServiceLocked

[-> ActiveServices.java]

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
    if (app.thread == null) {
        throw new RemoteException();
    }

    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    final boolean newService = app.services.add(r);

    //發送delay消息(SERVICE_TIMEOUT_MSG)
    bumpServiceExecutingLocked(r, execInFg, "create");
    mAm.updateLruProcessLocked(app, false, null);
    mAm.updateOomAdjLocked();
    boolean created = false;
    try {
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startLaunchedLocked();
        }
        mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
        //服務進入 onCreate() 【見流程13】
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        mAm.appDiedLocked(app); //應用死亡處理
        throw e;
    } finally {
        if (!created) {
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            if (newService) {
                app.services.remove(r);
                r.app = null;
            }
            //嘗試重新啟動服務
            if (!inDestroying) {
                scheduleServiceRestartLocked(r, false);
            }
        }
    }
    requestServiceBindingsLocked(r, execInFg);
    updateServiceClientActivitiesLocked(app, null, true);

    if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                null, null));
    }
    //服務 進入onStartCommand() 【見流程17】
    sendServiceArgsLocked(r, execInFg, true);
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }
    if (r.delayedStop) {
        r.delayedStop = false;
        if (r.startRequested) {
            stopServiceLocked(r); //停止服務
        }
    }
}

在bumpServiceExecutingLocked會發送一個延遲處理的消息SERVICE_TIMEOUT_MSG。在方法scheduleCreateService執行完成,也就是onCreate回調執行完成之後,便會remove掉該消息。但是如果沒能在延時時間之內remove該消息,則會進入執行service timeout流程。

13. ATP.scheduleCreateService

[-> ApplicationThreadProxy.java]

public final void scheduleCreateService(IBinder token, ServiceInfo info,
        CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    try {
        //【見流程14】
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        throw e;
    }
    data.recycle();
}

14 ATN.onTransact

[-> ApplicationThreadNative.java]

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
        data.enforceInterface(IApplicationThread.descriptor);
        IBinder token = data.readStrongBinder();
        ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
        CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
        int processState = data.readInt();
        // 【見流程15】
        scheduleCreateService(token, info, compatInfo, processState);
        return true;
    }
}

15 AT.scheduleCreateService

[-> ApplicationThread.java]

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;
    //發送消息 【見流程16】
    sendMessage(H.CREATE_SERVICE, s);
}

該方法的執行在ActivityThread線程

16. H.handleMessage

[-> ActivityThread.java]

public void handleMessage(Message msg) {
    switch (msg.what) {
        ...
        case CREATE_SERVICE:
            handleCreateService((CreateServiceData)msg.obj); //【見流程17】
            break;
        case BIND_SERVICE:
            handleBindService((BindServiceData)msg.obj);
            break;
        case UNBIND_SERVICE:
            handleUnbindService((BindServiceData)msg.obj);
            break;
        case SERVICE_ARGS:
            handleServiceArgs((ServiceArgsData)msg.obj);  // serviceStart
            break;
        case STOP_SERVICE:
            handleStopService((IBinder)msg.obj);
            maybeSnapshot();
            break;
    }
}

17. handleCreateService

[-> ActivityThread.java]

private void handleCreateService(CreateServiceData data) {
    //當應用處於後台即將進行GC,而此時被調回到活動狀態,則跳過本次gc。
    unscheduleGcIdler();
    //生成服務對象
    LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        //
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to instantiate service " + data.info.name + ": " + e.toString(), e);
        }
    }
    try {
        //創建ContextImpl對象
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
        service.onCreate(); //調用服務的 onCreate()方法 【見流程18】
        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) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to create service " + data.info.name
                + ": " + e.toString(), e);
        }
    }
}

18. Service.onCreate

public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
    public void onCreate(){    }
}

最終調用到抽象類Service.onCreate()方法,對於真正的Service都會通過覆寫該方式,調用真正Service子類的onCreate()方法。撥雲見日,到此總算是進入了Service的生命周期。

三、總結

在整個startService過程,從進程角度看服務啟動過程

  • Process A進程:是指調用startService命令所在的進程,也就是啟動服務的發起端進程,比如點擊桌面App圖標,此處Process A便是Launcher所在進程。
  • system_server進程:系統進程,是java framework框架的核心載體,裡面運行了大量的系統服務,比如這裡提供ApplicationThreadProxy(簡稱ATP),ActivityManagerService(簡稱AMS),這個兩個服務都運行在system_server進程的不同線程中,由於ATP和AMS都是基於IBinder接口,都是binder線程,binder線程的創建與銷毀都是由binder驅動來決定的,每個進程binder線程個數的上限為16。
  • Zygote進程:是由init進程孵化而來的,用於創建Java層進程的母體,所有的Java層進程都是由Zygote進程孵化而來;
  • Remote Service進程:遠程服務所在進程,是由Zygote進程孵化而來的用於運行Remote服務的進程。主線程主要負責Activity/Service等組件的生命周期以及UI相關操作都運行在這個線程; 另外,每個App進程中至少會有兩個binder線程 ApplicationThread(簡稱AT)和ActivityManagerProxy(簡稱AMP),當然還有其他線程,這裡不是重點就不提了。

start_service_process

圖中涉及3種IPC通信方式:BinderSocket以及Handler,在圖中分別用3種不同的顏色來代表這3種通信方式。一般來說,同一進程內的線程間通信采用的是 Handler消息隊列機制,不同進程間的通信采用的是binder機制,另外與Zygote進程通信采用的Socket

啟動流程:

  1. Process A進程采用Binder IPC向system_server進程發起startService請求;
  2. system_server進程接收到請求後,向zygote進程發送創建進程的請求;
  3. zygote進程fork出新的子進程Remote Service進程;
  4. Remote Service進程,通過Binder IPC向sytem_server進程發起attachApplication請求;
  5. system_server進程在收到請求後,進行一系列准備工作後,再通過binder IPC向remote Service進程發送scheduleCreateService請求;
  6. Remote Service進程的binder線程在收到請求後,通過handler向主線程發送CREATE_SERVICE消息;
  7. 主線程在收到Message後,通過發射機制創建目標Service,並回調Service.onCreate()方法。

到此,服務便正式啟動完成。當創建的是本地服務時,無需經過上述步驟2、3,直接創建服務即可。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved