欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Service啟動(dòng)流程刨析

 更新時(shí)間:2022年08月11日 08:50:03   作者:Android技術(shù)棧  
這幾天分析了一下的啟動(dòng)過(guò)程,于是乎,今天寫一下Service是如何啟動(dòng)的;?給我的感覺(jué)是這些啟動(dòng)過(guò)程并不復(fù)雜,千萬(wàn)不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個(gè)接著一個(gè),就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口

強(qiáng)調(diào)一下閱讀系統(tǒng)源碼,起碼要對(duì)進(jìn)程間通信要了解,對(duì)binder機(jī)制非常非常清楚,binder就是指南針,要不然你會(huì)暈頭轉(zhuǎn)向;強(qiáng)行閱讀,就容易睡著。

Service啟動(dòng)先來(lái)一張圖感受一下

這張圖能夠說(shuō)明一個(gè)大致的流程,但是服務(wù)的啟動(dòng)肯定不是這么簡(jiǎn)單,但是我們先簡(jiǎn)單的總結(jié)一下,逐漸深入。服務(wù)的啟動(dòng)形式有兩種,startService()和 binderService(),我們看startService()這一種。startService是ContextWrapper里面的方法。

ContextWrapper.java

  @Override
   public ComponentName startService(Intent service) {
       return mBase.startService(service);//mBase這里指的是ContextImpl類
   }

ContextImpl.java

   @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }
  private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            //檢驗(yàn)Intent
            validateServiceIntent(service);
             ......
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
             ......
            return cn;
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
    }

校驗(yàn)完Intent后,就調(diào)用ActivityManagerNative.getDefault(),獲取一個(gè)IActivityManager對(duì)象,將啟動(dòng)Service這件事情交給了IActivityManager。我們看一下ActivityManagerNative的類定義

public abstract class ActivityManagerNative extends Binder implements IActivityManager

這種模式是不是非常熟悉??? 繼承了Binder,實(shí)現(xiàn)了一個(gè)IActivityManager接口,這個(gè)跟我們生成了遠(yuǎn)程服務(wù)通信生成的AIDL的java文件怎么那么像,現(xiàn)在告訴你,這就是為了遠(yuǎn)程服務(wù)通信做準(zhǔn)備的,只是一般這種類我們都是自動(dòng)生成的,ActivityManagerNative 是谷歌的人自己寫

一個(gè)完整的AID L有兩部分,一個(gè)是個(gè)跟服務(wù)端通信的Stub,一個(gè)是跟客戶端通信的Proxy; ActivityManagerNative就是Stub,閱讀源碼發(fā)現(xiàn)在ActivityManagerNative 文件中還有個(gè)ActivityManagerProxy,那么跟客戶端通信的Proxy也有了。先看IActivityManager怎么獲取的

ActivityManagerNative.java

 static public IActivityManager getDefault() {
        return gDefault.get();
    }
  private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
          //獲取名為"activity"的服務(wù),服務(wù)都注冊(cè)到ServiceManager來(lái)統(tǒng)一管理
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

就是一個(gè)單例設(shè)計(jì)模式,獲取到服務(wù)對(duì)象IBinder,把這個(gè)IBinder轉(zhuǎn)換成IActivityManager返回了?,F(xiàn)在由IActivityManager啟動(dòng)服務(wù)。

 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);
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }

上面說(shuō)了ActivityManagerProxy作為binder通信的客戶端,ActivityManagerNative 作為binder通信的服務(wù)端; mRemote.transact()是binder通信的客戶端發(fā)起方法,經(jīng)過(guò)binder驅(qū)動(dòng),最后回到binder服務(wù)端ActivityManagerNative的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();
                        IApplicationThread app = ApplicationThreadNative.asInterface(b);
                        Intent service = Intent.CREATOR.createFromParcel(data);
                        String resolvedType = data.readString();
                        String callingPackage = data.readString();
                        int userId = data.readInt();
                        ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
                        reply.writeNoException();
                        ComponentName.writeToParcel(cn, reply);
                        return true;
                    }
        }
        .......
    }

ActivityManagerNative的真正實(shí)現(xiàn)是ActivityManagerService,所以binder通信的服務(wù)端的ActivityManagerService,ActivityManagerProxy.startService()最終調(diào)用ActivityManagerService.startService()。注意這就跨進(jìn)程了,ActivityManagerService是一個(gè)服務(wù)端的進(jìn)程??碅ctivityManagerService中的startService方法。

ActivityManagerService.java

 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ......
        synchronized(this) {
            .......
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

ActivityManagerService沒(méi)有直接干這個(gè)活,而是把這個(gè)任務(wù)交給了mService, mService 是一個(gè) ActiveServices 對(duì)象。在早期的安卓版本中并沒(méi)有這個(gè)類,后來(lái)重構(gòu)時(shí)抽出這個(gè)類專門用來(lái)管理Service.

ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, int userId)
            throws TransactionTooLargeException {
              ........
              return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }

tartServiceInnerLocked調(diào)用了 bringUpServiceLocked(),bringUpServiceLocked()內(nèi)部調(diào)用了realStartServiceLocked(),我們看realStartServiceLocked()方法。

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
       .......
        try {
            .......
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            ....
        } finally {
           ....
        }
        requestServiceBindingsLocked(r, execInFg);
        updateServiceClientActivitiesLocked(app, null, true);
        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }
       // 進(jìn)入onStartCommand()
        sendServiceArgsLocked(r, execInFg, true);
       ....
    }

這里的關(guān)鍵是

 app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),

app 是要運(yùn)行 Service 的進(jìn)程對(duì)應(yīng)的 ProcessRecord 對(duì)象,代表一個(gè)應(yīng)用進(jìn)程; 要區(qū)分一下,一般我們都是單方向通信,客戶端將處理請(qǐng)求發(fā)送給服務(wù)端,服務(wù)端處理后返回,如果要服務(wù)端向客戶端發(fā)送一個(gè)“請(qǐng)求”呢?這里的thread 是一個(gè) ApplicationThreadProxy 對(duì)象,它是應(yīng)用進(jìn)程的 ApplicatonThread 對(duì)象在 AMS 端的代理,AMS 靠它來(lái)和應(yīng)用進(jìn)程進(jìn)行通信。所以AMS和應(yīng)用進(jìn)程可以雙向通信了。

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 {
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        throw e;
    }
    data.recycle();
}

執(zhí)行mRemote.transact后,就會(huì)回調(diào)ApplicationThreadNative的onTransact,這是Binder的套路。

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();
        scheduleCreateService(token, info, compatInfo, processState);
        return true;
    }
    ...
}

內(nèi)部調(diào)用scheduleCreateService,看上面的圖,可以知道,scheduleCreateService是屬于ApplicatonThread的。

ApplicatonThread.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;
            sendMessage(H.CREATE_SERVICE, s);
        }

發(fā)送一個(gè)消息,這個(gè)消息都是由H類處理的,H類就是系統(tǒng)Hander,專門處理系統(tǒng)請(qǐng)求的; 比如一些Activity的生命周期等全在這里面。這個(gè) H對(duì)象是在應(yīng)用進(jìn)程的主線程中創(chuàng)建的,所以最終的結(jié)果是把創(chuàng)建 Service 的消息傳到了主線程,因此Service是運(yùn)行在主線程中的。

H.java

private class H extends Handler {
          .........
            public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            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);
            }
        }

ActivityThread.java

private void handleCreateService(CreateServiceData data) {
        .......
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            // 反射加載Service
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            .......
        }
        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
             //創(chuàng)建ContextImpl對(duì)象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
             //創(chuàng)建Application對(duì)象
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            //回調(diào)onCreate方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
              //調(diào)用服務(wù)創(chuàng)建完成
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
           .......
        }
    }

到此Service的onCreate就回調(diào)了,那么onStartCommand()何時(shí)回調(diào)呢?在realStartServiceLocked中調(diào)用了sendServiceArgsLocked(r, execInFg, true),sendServiceArgsLocked與上面類似,最終也是發(fā)送了一個(gè)(SERVICE_ARGS)消息。

ApplicationThread.java

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
            int flags ,Intent args) {
            ServiceArgsData s = new ServiceArgsData();
            s.token = token;
            s.taskRemoved = taskRemoved;
            s.startId = startId;
            s.flags = flags;
            s.args = args;
            sendMessage(H.SERVICE_ARGS, s);
        }

ActivityThread.java

private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                //onStartCommand回調(diào)
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }
                QueuedWork.waitToFinish();
                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    // nothing to do.
                }
                ensureJitEnabled();
            } catch (Exception e) {
               ......
            }
        }
    }

Service的onCreate的回調(diào)和onStartCommand的回調(diào)套路是完全一樣的,朋友們可以自己體會(huì),onCreate的回調(diào)先執(zhí)行scheduleCreateService()方法,最終回調(diào)Service.onCreate(); onStartCommand的回調(diào)先執(zhí)行scheduleServiceArgs()方法,最終回調(diào)Service.onStartCommand()

總結(jié)一下:

IActivityManager接口中定義了AMS向應(yīng)用程序(本例中即Service)提供的多種API,Activity通過(guò)ActivityManagerProxy就可以使用這些API,向AMS發(fā)出請(qǐng)求

所以是通過(guò)ActivityManagerProxy,調(diào)用ActivityManagerProxy的startService方法; 在內(nèi)部調(diào)用transact,然后會(huì)調(diào)用ActivityManagerNative中的onTransact()方法,在該方法中,將會(huì)r完成AMS與Activity的連接并調(diào)用AMS的startService()方法,那么AMS是如何Service所在的應(yīng)用程序呢?比如scheduleCreateService

原來(lái)ApplicationThreadProxy 是應(yīng)用進(jìn)程的 ApplicatonThread 對(duì)象在 AMS 端的代理,AMS 靠它來(lái)和應(yīng)用進(jìn)程進(jìn)行通信。這就是Activity與AMS之間的雙向Binder連接;Activity用IActivityManager提供的APIActivityManagerService提出執(zhí)行某個(gè)動(dòng)作的請(qǐng)求(本例中是啟動(dòng)RemoteService),ActivityManagerService通過(guò)IApplicationThread提供的API來(lái)控制Activity所在的應(yīng)用程序

上面的分析省去了很多的內(nèi)容,如果從進(jìn)程角度看服務(wù)啟動(dòng)過(guò)程。

  • Process A進(jìn)程: 是指調(diào)用startService命令所在的進(jìn)程,也就是啟動(dòng)服務(wù)的發(fā)起端進(jìn)程
  • system_server進(jìn)程: 系統(tǒng)進(jìn)程,是java framework框架的核心載體,里面運(yùn)行了大量的系統(tǒng)服務(wù),比如這里提供ApplicationThreadProxy,ActivityManagerService,這個(gè)兩個(gè)服務(wù)都運(yùn)行在system_server進(jìn)程的不同線程中
  • Zygote進(jìn)程: 是由init進(jìn)程孵化而來(lái)的,用于創(chuàng)建Java層進(jìn)程的母體,所有的Java層進(jìn)程都是由Zygote進(jìn)程孵化而來(lái)
  • Remote Service進(jìn)程: 遠(yuǎn)程服務(wù)所在進(jìn)程,是由Zygote進(jìn)程孵化而來(lái)的用于運(yùn)行Remote服務(wù)的進(jìn)程。主線程主要負(fù)責(zé)Activity/Service等組件的生命周期以及UI相關(guān)操作都運(yùn)行在這個(gè)線程; 另外,每個(gè)App進(jìn)程中至少會(huì)有兩個(gè)binder線程 ApplicationThread和ActivityManagerProxy

啟動(dòng)流程:

  • Process A進(jìn)程采用Binder IPC向system_server進(jìn)程發(fā)起startService請(qǐng)求;
  • system_server進(jìn)程接收到請(qǐng)求后,向zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求;
  • zygote進(jìn)程fork出新的子進(jìn)程Remote Service進(jìn)程;
  • Remote Service進(jìn)程,通過(guò)Binder IPC向sytem_server進(jìn)程發(fā)起attachApplication請(qǐng)求;
  • system_server進(jìn)程在收到請(qǐng)求后,進(jìn)行一系列準(zhǔn)備工作后,再通過(guò)binder IPC向remote Service進(jìn)程發(fā)送scheduleCreateService請(qǐng)求;
  • Remote Service進(jìn)程的binder線程在收到請(qǐng)求后,通過(guò)handler向主線程發(fā)送CREATE_SERVICE消息;
  • 主線程在收到Message后,通過(guò)發(fā)射機(jī)制創(chuàng)建目標(biāo)Service,并回調(diào)Service.onCreate()方法。 到此,服務(wù)便正式啟動(dòng)完成。當(dāng)創(chuàng)建的是本地服務(wù)或者服務(wù)所屬進(jìn)程已創(chuàng)建時(shí),則無(wú)需經(jīng)過(guò)上述步驟2、3,直接創(chuàng)建服務(wù)即可

到此這篇關(guān)于Android Service啟動(dòng)流程刨析的文章就介紹到這了,更多相關(guān)Android Service內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論