Service源碼淺析一

Service源碼淺析一
Service源碼淺析二
Service源碼淺析三
Service源碼淺析四

Service類的代碼量比較少,內(nèi)容沒什么可說的。
Service是一個(gè)抽象類。


Service

1. Start Service

    @Nullable
    public abstract ComponentName startService(Intent service);

start service其實(shí)調(diào)用的是Context的方法,Context的實(shí)現(xiàn)類是ContextWrapper,它的startService方法如下:

    @Override
    public @Nullable ComponentName startService(Intent service) {
        return mBase.startService(service);
    }

ContextWrapper使用代理模式,其中真正的實(shí)現(xiàn)類是mBase,mBase是ContextImpl的實(shí)例。
在ContextImpl中會(huì)依次調(diào)用 startService->startServiceCommon->ActivityManager.getService().startService

    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

ActivityManager.getService方法如上,ActivityManager其實(shí)就是ActivityManagerService的客戶端類。

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

這里用到了Singleton類,它是一個(gè)單例的工具類,在咱們得代碼中也可以使用,代碼我也貼一下

public abstract class Singleton<T> {

    @UnsupportedAppUsage
    public Singleton() {
    }

    @UnsupportedAppUsage
    private T mInstance;

    protected abstract T create();

    @UnsupportedAppUsage
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

通過IActivityManagerSingleton返回了IActivityManagerSingleton的Binder對(duì)象,猜測(cè)這里發(fā)生了進(jìn)程通信,詳細(xì)不深究了,后邊看AMS的時(shí)候補(bǔ)上,咱們先順流程。
接下來就進(jìn)入了ActivityManagerService進(jìn)程了,調(diào)用它的startService方法。
繼續(xù)走到ActiveServices的startServiceLocked,ActiveServices是ActivityManagerService的輔助類。
順著主線繼續(xù)走,ActiveServices#startServiceLocked -> startServiceInnerLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
-> IApplicationThread#scheduleCreateService
走到這里有發(fā)生了一次進(jìn)程通信,已經(jīng)進(jìn)入到對(duì)應(yīng)進(jìn)程里了,這里仍然疑點(diǎn)重重:

  1. 這里應(yīng)該發(fā)生了進(jìn)程創(chuàng)建;
  2. 如果是同一個(gè)進(jìn)程怎么處理的;
    細(xì)節(jié)留到后邊再補(bǔ),先順著流程走,在這之前先補(bǔ)個(gè)簡(jiǎn)圖,方便理解。


    startService

ApplicationThread是ActivityThread的內(nèi)部類,ActivityThread其實(shí)就是應(yīng)用的進(jìn)程入口,進(jìn)程創(chuàng)建時(shí)會(huì)觸發(fā)ActivityThread#main函數(shù)。
scheduleCreateService會(huì)向主線程的handler中發(fā)送創(chuàng)建服務(wù)的消息,最終調(diào)用handleCreateService,在此方法中,如果Application對(duì)象未創(chuàng)建,會(huì)創(chuàng)建Application對(duì)象并觸發(fā)其onCreate方法。同時(shí)實(shí)例化Service并調(diào)用其onCreate方法。

onCreate方法執(zhí)行之后咱們回到 ActiveServices#realStartServiceLocked,這里觸發(fā)了IApplicationThread#scheduleCreateService之后,后邊還觸發(fā)了sendServiceArgsLocked,在這個(gè)方法中最終會(huì)觸發(fā)r.app.getThread().scheduleServiceArgs,這里有一次進(jìn)程間通信再次來到ApplicationThread。在ApplicationThread中會(huì)觸發(fā) Service#onStartCommand。

到這里Start Service流程基本結(jié)束了。

2. Bind Service

    public abstract boolean bindService(@RequiresPermission @NonNull Intent service,
            @NonNull ServiceConnection conn, int flags);

我們按照同樣的方式繼續(xù)分析bindService
首先來到 ContextImpl#bindServiceCommon,在這里會(huì)調(diào)用ActivityManager.getService().bindServiceInstance,這里發(fā)生了進(jìn)程通信,進(jìn)入AMS進(jìn)程。
ActiveServices#bindServiceLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
在realStartServiceLocked方法中會(huì)觸發(fā)thread.scheduleCreateService來創(chuàng)建Service實(shí)例。
Service onCreate執(zhí)行之后接下來繼續(xù)執(zhí)行requestServiceBindingsLocked -> r.app.getThread().scheduleBindService,又是進(jìn)程通信,同樣的套路觸發(fā)ApplicationThread#handleBindService,然后觸發(fā)Service的onBind返回一個(gè)IBinder用于進(jìn)程間通信。
接下來是AMS的publishService -> ActiveServices#publishServiceLocked,最終會(huì)觸發(fā)IServiceConnection#connected回調(diào)方法,這里要?jiǎng)x一腳車了,這個(gè)IServiceConnection是個(gè)什么東西?
這就不得不回到起點(diǎn)了,bindService時(shí)會(huì)傳入ServiceConnection,這個(gè)參數(shù)經(jīng)過LoadedApk#getServiceDispatcher -> getServiceDispatcherCommon,在這個(gè)方法中會(huì)創(chuàng)建ServiceDispatcher,然后又會(huì)創(chuàng)建InnerConnection,這個(gè)就是我們要找的IServiceConnection

        private static class InnerConnection extends IServiceConnection.Stub {
            @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }

觸發(fā)它的connected,最終會(huì)調(diào)用ServiceDispatcher#connected

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

在這三個(gè)分支中都會(huì)觸發(fā)doConnected,最終會(huì)調(diào)用onServiceConnected回調(diào)方法,至此bindService流程結(jié)束了。
補(bǔ)充一點(diǎn):這里mActivityThread就是主線程的Handler,可以得出onServiceConnected最終會(huì)運(yùn)行在主線程。

3. Unbind Service

public abstract void unbindService(@NonNull ServiceConnection conn);

同樣執(zhí)行ContextImpl#unbindService方法

    @Override
    public void unbindService(ServiceConnection conn) {
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                    getOuterContext(), conn);
            try {
                ActivityManager.getService().unbindService(sd);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
    }

這里的mPackageInfo就是LoadedApk實(shí)例。
AMS#unbindService -> ActiveServices#unbindServiceLocked -> removeConnectionLocked -> ActivityThread#scheduleUnbindService -> handleUnbindService -> Service#onUnbind -> AMS#unbindFinished -> ActiveServices#unbindFinishedLocked
回到ActiveServices#removeConnectionLocked -> removeConnectionLocked -> bringDownServiceIfNeededLocked -> bringDownServiceLocked -> ActivityThread#scheduleStopService -> Service#onDestroy

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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