之前写过一篇从AIDL看Android跨进程通信 从Java层次去分析AIDL运行的原理,当时主要是为了学习Binder机制而写的,但是Binder机制比较复杂,打算过段时间单独的写一篇来分析。本篇文章分析startService的启动过程,也会涉及到使用Binder机制来进行跨进程通信,但是不会分析Binder机制的细节。不过还是强烈建议大家学习Binder机制,至少要了解Binder的基本架构,Android经常使用Binder来进行跨进程通信。
  在Android中启动Service和Activity统一由ActivityManagerService(简称AMS)管理,AMS在系统启动时,就已经在ServiceManager中注册了,存活于system_server进程中。先来了解一下ActivityManagerService相关的类:
  
  从类图可以看到这是典型的Binder机制,如果使用过AIDL的话,对IBinder,IInterface应该很熟悉。IActivityManager继承自IInterface,是用来管理Activity和Service的接口。ActivityManagerProxy从名字可以看出其是代理,并且是AMS在普通应用进程中的代理,通过它可以使用AMS的功能。ActivityManagerNative则可以看做AMS和Binder之间的中介,这样AMS就可以通过它向客户端提供服务了。

  一 :从客户进程启动Service
  我们还是使用从AIDL看Android跨进程通信 中的例子,从MainActivity来调用startService,一步一步分析:
  1.1 ContextWrapper.java
  

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

  这里的mBase实际是ContextImpl的实例,所以接着看
  
  1.2 ContextImpl.java
  
  /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 {            validateServiceIntent(service);            service.prepareToLeaveProcess(this);            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 e.rethrowFromSystemServer();        }    }

  在startServiceCommon()方法中首先验证intent是否合法,然后重点看第11~13行。想要继续跟下去就得先搞清楚ActivityManagerNative.getDefault() 是个什么鬼。

  1.3 ActivityManagerNative.java
  /frameworks/base/core/java/android/app/ActivityManagerNative.java

/**     * Cast a Binder object into an activity manager interface, generating     * a proxy if needed.     */    static public IActivityManager asInterface(IBinder obj) {        if (obj == null) {            return null;        }        IActivityManager in =            (IActivityManager)obj.queryLocalInterface(descriptor);        if (in != null) {            return in;        }        return new ActivityManagerProxy(obj);    }    /**     * Retrieve the system's default/global activity manager.     */    static public IActivityManager getDefault() {        return gDefault.get();    }...省略...private static final Singleton gDefault = new Singleton() {        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;        }    };

  第22行,将会回调Singleton的create()方法,对应28~38行代码,第29行通过ServiceManager.getService("activity") 可以获取一个IBinder,AMS在系统启动的时候已经在ServiceManager中注册过,这里我们只用知道通过这个IBinder对象(具体是BinderProxy对象)我们可以发起远程调用。通过第15行生成了一个ActivityManagerProxy并且将其作为单例保存起来,下次调用可以直接使用了。
  ![这里写图片描述]
  
  
  上图也可以印证我们的分析。ActivityManagerNative.getDefault() 返回的是ActivityManagerProxy实例,那么1.2中将会调用ActivityManagerProxy.startService()方法。

  1.4 ActivityManagerProxy.java
  该类是在ActivityMangerNative中声明。
  

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

  第12行mRemote是在ActivityManagerProxy的构造方法中赋值的,还记得刚刚new ActivityManagerProxy时传入了一个IBinder(BinderProxy)吗?通过它的transact()方法像远端AMS发起请求。

  二 system_server进程中AMS响应

  根据Binder机制,ActivityManagerNative的onTransact()方法将会回调,因为这个方法比较长,我只截取了响应startService动作的代码。
  
  2.1 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();            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;        }        ...省略...       }     }

  第9行,这里将要涉及到另外一个跨进程通信,主要是干什么的呢,我们知道MainActivity所在进程A通过IActivityManager接口可以调用AMS的服务,那么如果AMS想要访问进程A的服务该怎么办呢,通过这里的IApplicationThread接口可以做到。下面是相关类图:
  
  
  
  和之前的IActivityManager类似,使用IApplicationThread也是基于Binder架构的,所以它们的结构都很像,所以这里的ApplicationThreadProxy就是A进程在AMS的一个Binder代理,通过它AMS就可以调用A进程的服务。
  第14行startService()是IActivityManager接口的方法,因为ActivityManagerNative是一个抽象类,并且AMS继承了ActivityManagerNative,所以这里startService()的真正实现在ActivityManagerService中。

  2.2 ActivityManagerService.java
  /frameworks/base/services/core/java/com/android/server/am
  

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

  重点看第21,22行
  mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid, callingPackage, userId);
  mServices是ActiveServices的实例,所以将要执行ActiveServices的startServiceLocked()方法,一般带有Locked后缀的都是需要保证线程安全的。

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

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,            int callingPid, int callingUid, String callingPackage, final int userId)            throws TransactionTooLargeException {        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service                + " type=" + resolvedType + " args=" + service.getExtras());        final boolean callerFg;        if (caller != null) {            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);            if (callerApp == null) {                throw new SecurityException(                        "Unable to find app for caller " + caller                        + " (pid=" + Binder.getCallingPid()                        + ") when starting service " + service);            }            callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;        } else {            callerFg = true;        }        ServiceLookupResult res =            retrieveServiceLocked(service, resolvedType, callingPackage,                    callingPid, callingUid, userId, true, callerFg, false);        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.mUserController.exists(r.userId)) {            Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);            return null;        }        if (!r.startRequested) {            final long token = Binder.clearCallingIdentity();            try {                // Before going further -- if this app is not allowed to run in the                // background, then at this point we aren't going to let it period.                final int allowed = mAm.checkAllowBackgroundLocked(                        r.appInfo.uid, r.packageName, callingPid, true);                if (allowed != ActivityManager.APP_START_MODE_NORMAL) {                    Slog.w(TAG, "Background start not allowed: service "                            + service + " to " + r.name.flattenToShortString()                            + " from pid=" + callingPid + " uid=" + callingUid                            + " pkg=" + callingPackage);                    return null;                }            } finally {                Binder.restoreCallingIdentity(token);            }        }        NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(                callingUid, r.packageName, service, service.getFlags(), null, r.userId);        // If permissions need a review before any of the app components can run,        // we do not start the service and launch a review activity if the calling app        // is in the foreground passing it a pending intent to start the service when        // review is completed.        if (Build.PERMISSIONS_REVIEW_REQUIRED) {            if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,                    callingUid, service, callerFg, userId)) {                return null;            }        }        if (unscheduleServiceRestartLocked(r, callingUid, false)) {            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);        }        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.mUserController.hasStartedUserState(r.userId)) {            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {                // If this is not coming from a foreground caller, then we may want                // to delay the start if there are already other background services                // that are starting.  This is to avoid process start spam when lots                // of applications are all handling things like connectivity broadcasts.                // We only do this for cached processes, because otherwise an application                // can have assumptions about calling startService() for a service to run                // in its own process, and for that process to not be killed before the                // service is started.  This is especially the case for receivers, which                // may start a service in onReceive() to do some additional work and have                // initialized some global state as part of that.                if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of "                        + r + " in " + proc);                if (r.delayed) {                    // This service is already scheduled for a delayed start; just leave                    // it still waiting.                    if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r);                    return r.name;                }                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {                    // Something else is starting, delay!                    Slog.i(TAG_SERVICE, "Delaying start of: " + r);                    smap.mDelayedStartList.add(r);                    r.delayed = true;                    return r.name;                }                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);                addToStarting = true;            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {                // We slightly loosen when we will enqueue this new service as a background                // starting service we are waiting for, to also include processes that are                // currently running other services or receivers.                addToStarting = true;                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,                        "Not delaying, but counting as bg: " + r);            } else if (DEBUG_DELAYED_STARTS) {                StringBuilder sb = new StringBuilder(128);                sb.append("Not potential delay (state=").append(proc.curProcState)                        .append(' ').append(proc.adjType);                String reason = proc.makeAdjReason();                if (reason != null) {                    sb.append(' ');                    sb.append(reason);                }                sb.append("): ");                sb.append(r.toString());                Slog.v(TAG_SERVICE, sb.toString());            }        } else if (DEBUG_DELAYED_STARTS) {            if (callerFg) {                Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="                        + callingUid + " pid=" + callingPid + "): " + r);            } else if (r.app != null) {                Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);            } else {                Slog.v(TAG_SERVICE,                        "Not potential delay (user " + r.userId + " not started): " + r);            }        }        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);    }

  这个方法比较长,为了方便分析,先把介绍一下方法的参数:
    caller:IApplicationThread类型,这里具体是ApplicationThreadProxy类型,通过它可以和应用进程进行通信。
    service:Intent类型,主要包含了将要启动service的信息
    resolvedType:String 类型,这里为null
    callingPid:发起call的进程的pid
    callingUid:发起call进程的uid
    callingPackage:发起call进程的package信息
    userId:这里为0
  如图:

  

  第22、23行代码主要是检索服务信息,可以获取到ServiceRecord和相应的权限信息。84~145行主要是对非前台进程的调度。最终会调用第147行startServiceInnerLocked()方法。  

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {        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();        }        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, 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 (DEBUG_DELAYED_SERVICE) {                RuntimeException here = new RuntimeException("here");                here.fillInStackTrace();                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);            } else if (DEBUG_DELAYED_STARTS) {                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);            }            if (first) {                smap.rescheduleDelayedStarts();            }        } else if (callerFg) {            smap.ensureNotStartingBackground(r);        }        return r.name;    }

  第11行代码会调用bringUpServiceLocked(),从名字可以看出,这里应该会生成目标Service,并且会判断目标Service的进程是否存在,如果存在则直接去生成,如果不存在,则从Zygote fork一个进程,然后在生成相应的Service实例。
  

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,            boolean whileRestarting, boolean permissionsReviewRequired)            throws TransactionTooLargeException {        //Slog.i(TAG, "Bring up service:");        //r.dump("  ");        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;        }        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);        // We are now bringing the service up, so no longer in the        // restarting state.        if (mRestartingServices.remove(r)) {            r.resetRestartCounter();            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_SERVICE, "REM FR DELAY LIST (bring up): " + r);            getServiceMap(r.userId).mDelayedStartList.remove(r);            r.delayed = false;        }        // Make sure that the user who owns this service is started.  If not,        // we don't want to allow it to run.        if (!mAm.mUserController.hasStartedUserState(r.userId)) {            String msg = "Unable to launch app "                    + r.appInfo.packageName + "/"                    + r.appInfo.uid + " for service "                    + r.intent.getIntent() + ": user " + r.userId + " is stopped";            Slog.w(TAG, msg);            bringDownServiceLocked(r);            return msg;        }        // Service is now being launched, its package can't be stopped.        try {            AppGlobals.getPackageManager().setPackageStoppedState(                    r.packageName, false, r.userId);        } catch (RemoteException e) {        } catch (IllegalArgumentException e) {            Slog.w(TAG, "Failed trying to unstop package "                    + r.packageName + ": " + e);        }        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;        final String procName = r.processName;        ProcessRecord app;        if (!isolated) {            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid                        + " app=" + app);            if (app != null && app.thread != null) {                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) {                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);                }                // If a dead object exception was thrown -- fall through to                // restart the application.            }        } else {            // If this service runs in an isolated process, then each time            // we call startProcessLocked() we will get a new isolated            // process, starting another process if we are currently waiting            // for a previous process to come up.  To deal with this, we store            // in the service any current isolated process it is running in or            // waiting to have come up.            app = r.isolatedProc;        }        // Not running -- get it started, and enqueue this service record        // to be executed when the app comes up.        if (app == null && !permissionsReviewRequired) {            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";                Slog.w(TAG, msg);                bringDownServiceLocked(r);                return msg;            }            if (isolated) {                r.isolatedProc = app;            }        }        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) {                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,                        "Applying delayed stop (in bring up): " + r);                stopServiceLocked(r);            }        }        return null;    }

  程序会运行到第60行会获取目标进程的信息,63行会判断进程是否存在,如果存在直接会运行第66行realStartServiceLocked(从方法名可以看出真正的启动Service应该就在这个方法中)方法,并返回。如果不存在则会执行到第89行的mAm.startProcessLocked方法,这里的mAm是AMS的实例,所以程序会回到AMS的startProcessLocked方法。通过分析我们验证了之前的判断。并且还可以预测,将来在目标进程生成之后,还是会调用realStartServiceLocked方法去生成Service。

  三 AMS通知Zygote孵化目标进程
  根据之前的分析,到这一步,AMS将会通知Zygote去孵化目标进程。这个过程也是一个跨进程的通信,但是并不是Binder去实现的,而是使用的Socket,Zygote孵化进程将来也会去写一篇文章去分析,这里只用知道通过其生成了一个目标进程。目标进程又会通过Binder向system_server进程发起attachApplication请求。那么此时又会回调到AMS的attachApplication方法。
  
  四 AMS通知目标进程创建并启动Service
  4.1 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);        }    }

  基于第三节的分析,在Zygote孵化目标进程成功后,目标进程会通过Binder请求调用attachApplication服务,所以用调用上边的代码。第6行代码会接着调用attachApplicationLocked(之前已经说过方法名带Locked一般表示线程安全)方法,由于这个方法比较长,由于篇幅限制,我只截取最重要的一部分
  

private final boolean attachApplicationLocked(IApplicationThread thread,            int pid) {            ...省略...             boolean badApp = false;        boolean didSomething = false;        // See if the top visible activity is waiting to run in this process...        if (normalMode) {            try {                if (mStackSupervisor.attachApplicationLocked(app)) {                    didSomething = true;                }            } catch (Exception e) {                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);                badApp = true;            }        }        // Find any services that should be running in this process...        if (!badApp) {            try {                didSomething |= mServices.attachApplicationLocked(app, processName);            } catch (Exception e) {                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);                badApp = true;            }        }            ...省略...            }

  第22行 mServices.attachApplicationLocked(),mServices我们已经遇到过了,就是ActiveServices,那么又会执行其对应的方法。
  
  4.2 ActiveServices.java
  

boolean attachApplicationLocked(ProcessRecord proc, String processName)            throws RemoteException {        boolean didSomething = false;        // Collect any services that are waiting for this process to come up.        if (mPendingServices.size() > 0) {            ServiceRecord sr = null;            try {                for (int i=0; isize(); 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);                    realStartServiceLocked(sr, proc, sr.createdFromFg);                    didSomething = true;                    if (!isServiceNeeded(sr, false, false)) {                        // We were waiting for this service to start, but it is actually no                        // longer needed.  This could happen because bringDownServiceIfNeeded                        // won't bring down a service that is pending...  so now the pending                        // is done, so let's drop it.                        bringDownServiceLocked(sr);                    }                }            } 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;            for (int i=0; isize(); 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;    }

  第19行realStartServiceLocked(sr, proc, sr.createdFromFg);还记得么,在第二节最后,我们分析了孵化目标进程后,最后还是会执行realStartServiceLocked,在这里得到了印证。
  

 private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {        if (app.thread == null) {            throw new RemoteException();        }        if (DEBUG_MU)            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid                    + ", ProcessRecord.uid = " + app.uid);        r.app = app;        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();        final boolean newService = app.services.add(r);        bumpServiceExecutingLocked(r, execInFg, "create");        mAm.updateLruProcessLocked(app, false, null);        mAm.updateOomAdjLocked();        boolean created = false;        try {            if (LOG_SERVICE_START_STOP) {                String nameTerm;                int lastPeriod = r.shortName.lastIndexOf('.');                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;                EventLogTags.writeAmCreateService(                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);            }            synchronized (r.stats.getBatteryStats()) {                r.stats.startLaunchedLocked();            }            mAm.notifyPackageUse(r.serviceInfo.packageName,                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);            r.postNotification();            created = true;        } catch (DeadObjectException e) {            Slog.w(TAG, "Application dead when creating service " + r);            mAm.appDiedLocked(app);            throw e;        } finally {            if (!created) {                // Keep the executeNesting count accurate.                final boolean inDestroying = mDestroyingServices.contains(r);                serviceDoneExecutingLocked(r, inDestroying, inDestroying);                // Cleanup.                if (newService) {                    app.services.remove(r);                    r.app = null;                }                // Retry.                if (!inDestroying) {                    scheduleServiceRestartLocked(r, false);                }            }        }        if (r.whitelistManager) {            app.whitelistManager = true;        }        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));        }        sendServiceArgsLocked(r, execInFg, true);        if (r.delayed) {            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);            getServiceMap(r.userId).mDelayedStartList.remove(r);            r.delayed = false;        }        if (r.delayedStop) {            // Oh and hey we've already been asked to stop!            r.delayedStop = false;            if (r.startRequested) {                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,                        "Applying delayed stop (from start): " + r);                stopServiceLocked(r);            }        }    }

  这里主要看32~34行 app.thread.scheduleCreateService()其中app.thread是IApplicationThread,可见这里是system_server进程需要调用目标进程scheduleCreateService,那么在第二节分析,其实IApplicationThread的具体实现也就是ApplicationThreadProxy,通过它发起Binder通信。

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

  第10~11行,发起远程Binder通信,标识为SCHEDULE_CREATE_SERVICE_TRANSACTION,通过binder机制,最终将在ApplicationThreadNative的onTransact中响应。

  4.4 ApplicationThreadNative.java
  

 @Override    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;        }        ......        }        return super.onTransact(code, data, reply, flags);        }

  第12行scheduleCreateService方法,真正的实现是在ApplicationThread,原因是ApplicationThreadNative是个抽象类,ApplicationThread是其实现类。

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

  第9行,sendMessage()发送了一个tag为H.CREATE_SERVICE的消息,这里H类继承自Handler,是ActivityThread中的内部类,主要用于处理各种消息

  4.6 ActivityThread::H.java

public void handleMessage(Message msg) {    switch (msg.what) {                case CREATE_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));                    handleCreateService((CreateServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                 }     }

  第5行,handleCreateService()

private void handleCreateService(CreateServiceData data) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        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 {            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);            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();            mServices.put(data.token, service);            try {                ActivityManagerNative.getDefault().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        } catch (Exception e) {            if (!mInstrumentation.onException(service, e)) {                throw new RuntimeException(                    "Unable to create service " + data.info.name                    + ": " + e.toString(), e);            }        }    }

  第6~7行获取apk的信息,包括路径,包名。
  第10~11行通过ClassLoader将对应名字的Service加载到内存中来,这样就获取到了Service的对象。
  第23~24行获取ContextImpl对象。
  第26行获取Application对象。
  第27~28行通过attach方法将contextImpl,Application与Service对象关联起来。
  第29行调用onCreate方法,一般我们在使用Service时会重写该方法。这里Service的生命周期就开始了。
  第32~33行通过IActivityManager通知AMS 我们需要的Service已经启动了。
  上述整个启动过程的时序图:
  
  
  

更多相关文章

  1. Android图
  2. Android自适应不同屏幕几种方法
  3. 简单解释Android中的任务、进程和线程
  4. Android(安卓)将 android view 的位置设为右下角的解决方法
  5. SEAndroid安全机制简要介绍和学习计划
  6. android使用mysql的方法总结
  7. Unity和Android互相调用方法
  8. Android(安卓)注解基本使用
  9. Android应用程序进程启动过程的源代码分析

随机推荐

  1. ADB 实现Android Http 代理
  2. Android 异步加载图片(扩展后)
  3. 【Android外文翻译 - 01】避免内存泄漏
  4. Android(安卓)短信拦截+来去电话拦截
  5. Android利用SQLite制作最简单成语小词典
  6. android获取图片文件头信息
  7. Android的屏幕多样性支持
  8. 关于Android(安卓)ListView组件中android
  9. Android 关闭开启蓝牙
  10. Android 为图片添加文字水印