Service 源碼看啟動過程

Service兩次IPC過程

service_ipc.png

Service 啟動

我們知道開啟Service有兩種,一種是 直接startService(intent); 另外一種是bindService(intent,mConn, Service.BIND_AUTO_CREATE);

startService()

先看看startService()是如果啟動Service。在Activity中直接startService(),是直接ContextWapper中的startService(Intent service)。

ContextWapper.java

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

這里的 mBase 是在Activity啟動的時候通過 attachBaseContext進來的一個Context的實現(xiàn),實際上是ContextImpl
也就是說實際上是調(diào)用ContextImpl中的startService(service)。

ContextImpl.java

@Override
public ComponentName startService(Intent service) {
    //判斷警告是否是系統(tǒng)進程直接調(diào)用方法。
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, mUser);
}

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        //驗證service是否為空。
        validateServiceIntent(service);
        //準備intent leave app process。
        service.prepareToLeaveProcess();

        //正在啟動的是通過AMS啟動.
        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);
    }
}

這邊通過ContextImpl中的startService(service)最后調(diào)用startServiceCommon()的方法。
注意startServiceCommon()中的ActivityManagerNative.getDefault().startService() 我們看一下ActivityManagerNative 是什么東西.

ActivityManagerNative類的定義是這樣的:

public abstract class ActivityManagerNative extends Binder implements IActivityManager{}

這邊ActivityManagerNative是一個典型的Binder對象,繼承Binder并實現(xiàn)一個接口。這邊如果不理解Binder,建議先去學習了解Binder,了解Android的IPC機制。4大組件底層的啟動大部分都是通過Binder進行關(guān)聯(lián)啟動。

如果了解Binder,那我們繼續(xù)下去,我們在寫AIDL的時候,IDE自動幫我們生成Binder代碼,我們知道Binder有兩個內(nèi)容,一個是Stub,用來服務(wù)端通信的,還有一個Proxy代理用來客戶端信息。而ActivityManagerNative本身就是一個Stub,它是由Google自己寫的一個Binder。ActivityManagerNative 里面也有一個Proxy。就是ActivityManagerProxy。

class ActivityManagerProxy implements IActivityManager{
    private IBinder mRemote;

    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

    public IBinder asBinder()
    {
        return mRemote;
    }
    
    .....
    
}

看這個跟IDE自動生成的代碼是一樣的。
我們接著上面的分析,在ContextImpl中ActivityManagerNative.getDefault(),實際上是一由一個自己封裝Singleton單例對象。在get()的時候如果是第一次則會調(diào)用create().

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

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            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;
        }
    };

Singleton.java

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

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

在這里將獲取的IBinder轉(zhuǎn)成IActivityManager 對象。ActivityManagerNative.getDefault().startService()實際上是調(diào)用IActivityManager.startService(). 由上面分析的Binder,我們可以知道IActivityManager.startService()就是從客戶端調(diào)用startService,也就是在Proxy里面調(diào)用startService()。

ActivityManagerProxy.startService:

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

注意這句:mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
通過transact調(diào)用Binder的服務(wù)端的方法。

@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;
    }
    ...
    
    }
}

這里的startService(app, service, resolvedType, callingPackage, userId);具體實現(xiàn)實際上有ActivityManagerService子類實現(xiàn)的。

ActivityManagerService.java

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, String callingPackage, int userId)
        throws TransactionTooLargeException {
    enforceNotIsolatedCaller("startService");
    // Refuse possible leaked file descriptors
    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();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, callingPackage, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

接著調(diào)用mServices.startServiceLocked()方法,mServices是ActiveServices。

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

startServiceInnerLocked:

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
 ....
 
  String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    if (error != null) {
        return new ComponentName("!!", error);
    }
    
    ...
}

這里調(diào)用bringUpServiceLocked,而在它的內(nèi)部實際調(diào)用了realStartServiceLocked()方法。

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting) throws TransactionTooLargeException {
      
    ...
    if (!isolated) {
        ...
        try {
            app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
            realStartServiceLocked(r, app, execInFg);
            return null;
        } catch (TransactionTooLargeException e) {
            throw e;
        } catch (RemoteException e) {
          
    }
    ...
}

看一下realStartServiceLocked():

 private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
            
    if (app.thread == null) {
            throw new RemoteException();
    } 
    
    try {
        ...
        //回調(diào)onCreate
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        ...
    }
    
    ...
    //回調(diào)onStartCommand
    sendServiceArgsLocked(r, execInFg, true);
    ...
                
}

這邊重點看app.thread.scheduleCreateService() ,這里的app.thread是IApplicationThread。而在ActivityManagerNative里的START_SERVICE_TRANSACTION有這句:
IApplicationThread app = ApplicationThreadNative.asInterface(b); 我們的這個app.thread也是ApplicationThreadNative里的Binder。這邊又是一個Binder對象。

同樣ApplicationThreadNative也是一個Stub,里面的ApplicationThreadProxy是一個Proxy。所以這里app.thread.scheduleCreateService()實際是ApplicationThreadNative.scheduleCreateService().

 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) {
        Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
        throw e;
    }
    data.recycle();
}

調(diào)用 mRemote.transact(),則回調(diào)Proxy里的SCHEDULE_CREATE_SERVICE_TRANSACTION這個code。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    
    ...
    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;
    }
    ...
}

ApplicationThreadNative的具體實現(xiàn)是ApplicationThread:

private class ApplicationThread extends ApplicationThreadNative {
    ...
    
    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);
    }
    ...
}

這邊通過sendMessage()發(fā)送消息,由H來處理,H是系統(tǒng)的Handler。

private class H extends Handler {
    public void handleMessage(Message msg) {
        ...
        case CREATE_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        
        ...
    }
}

在這里接著調(diào)用handleCreateService()。

private void handleCreateService(CreateServiceData data) {

    LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();

            //反射獲取Service
            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 {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            //創(chuàng)建ContextImpl對象。
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //service attach操作
            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ù)完成.
                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);
            }
        }

}

到這里Service的onCreate()方法回調(diào)了。按照Service的生命周期,用startService方式啟動Service接著會調(diào)用onStartCommand(),那這個是在哪里回調(diào)的?其實是在realStartServiceLocked()里的sendServiceArgsLocked

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
    
    ...
     while (r.pendingStarts.size() > 0) {
        ...
        try {
            ...
            r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
        }
        ...
     }
}

同樣到了ApplicationThread的scheduleServiceArgs().

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

這樣就又到了H里面了

 case SERVICE_ARGS:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
        handleServiceArgs((ServiceArgsData)msg.obj);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;
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) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to start service " + s
                        + " with " + data.args + ": " + e.toString(), e);
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容