Service组件的启动机制深入学习

Service组件的启动机制深入学习_第1张图片

一、通过startService方式启动

1、ContextWrapper#startService:

/** @path: \frameworks\base\core\java\android\content\ContextWrapper.java **/
@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}
mBase的类型是ContextImpl;


2、ContextImpl#StartService:

/** @path: \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 {
        // 验证Intent是否合法
        validateServiceIntent(service);
        service.prepareToLeaveProcess();
        // t通过AMS来启动Service
        ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
        // 处理返回的Service组件信息是否合法
        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) {
        return null;
    }
}
上面代码中主要步骤是ActivityManagerNative.getDefault().startService;从 Activity组件启动过程及ActivityManagerService(AMS)(一)》中知道ActivityManagerNative.getDefault()的类型其实是AMS的代理:ActivityManagerProxy;则下面调用ActivityManagerProxy的startService函数;(ActivityManagerProxy是ActivityManagerNative的内部类);


3、ActivityManagerProxy#startService:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public ComponentName startService(IApplicationThread caller, Intent service,
                                      String resolvedType, 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.writeInt(userId);
        // IPC消息传递,消息类型:START_SERVICE_TRANSACTION
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }
}
类似于Activity的启动过程,最终仍是通过AMS发送 START_SERVICE_TRANSACTION 消息来startService;

ActivityManagerService处理START_SERVICE_TRANSACTION类型消息的函数为startService。


4、ActivityManagerService#startService:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
                                  String resolvedType, int userId) {
    enforceNotIsolatedCaller("startService");
    // 不处理包含文件描述符的Intent消息
    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    synchronized(this) {
        
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        // @value final ActiveServices mServices;
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}
上面的处理逻辑较为简单,首先避免处理包含有文件描述符的Intent,以保证系统安全;然后调用ActiveServices的startServiceLocked函数;


5、ActiveServices#startServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
ComponentName startServiceLocked(IApplicationThread caller,
                                 Intent service, String resolvedType,
                                 int callingPid, int callingUid, int userId) {
    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        .....
        callerFg = callerApp.setSchedGroup != android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }

    // 注意该函数,该函数会将Service信心封装成ServiceLookupResult类型返回
    ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, 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");
    }

    // 类似于ActivityRecord,ServiceRecord是记录Service相关信息的数据结构
    ServiceRecord r = res.record;

    if (!mAm.getUserManagerLocked().exists(r.userId)) {
        return null;
    }

    .......
    // 调用此函数继续启动Service
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
    注意retrieveServiceLocked函数,该函数会在AMS中查找是否已经存在一个与参数service(Intent)对应的ServiceRecord对象(类似于ActivityRecord,ServiceRecord是用来描述Service组件的数据结构);如果不存在,则AMS会到PMS中获取与参数service相对应的一个Service组件信息,将组件信息封装成ServiceRecord,进而再封装成ServiceLookupResult对象返回。

获取到serviceRecord后,继续调用startServiceInnerLocked来启动Service。


6、ActiveServices#retrieveServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private ServiceLookupResult retrieveServiceLocked(Intent service,
                                                  String resolvedType, int callingPid, int callingUid, int userId,
                                                  boolean createIfNeeded, boolean callingFromFg) {
    ServiceRecord r = null;

    userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
            false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);

    // 根据userId获取ServiceMap,根据名称很容易知道这里是保存Service组价的地方
    ServiceMap smap = getServiceMap(userId);
    // 查找smap中是否已经存在了service对应的Service组件信息
    final ComponentName comp = service.getComponent();
    if (comp != null) {
        // 根据组件名查找
        r = smap.mServicesByName.get(comp);
    }
    if (r == null) {
        // 根据Intent Filter查找 (可以看到分别对应显式、隐式两种启动方式)
        Intent.FilterComparison filter = new Intent.FilterComparison(service);
        r = smap.mServicesByIntent.get(filter);
    }

    // 如果为查找到
    if (r == null) {
        try {
            // AMS会继续往PMS中去获取相对应的Service组件信息(manifest中定义的service)
            ResolveInfo rInfo =
                    AppGlobals.getPackageManager().resolveService(
                            service, resolvedType,
                            ActivityManagerService.STOCK_PM_FLAGS, userId);
            ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
            if (sInfo == null) {
                Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
                        ": not found");
                return null;
            }
            ComponentName name = new ComponentName(sInfo.applicationInfo.packageName, sInfo.name);
            if (userId > 0) {
                if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                        sInfo.name, sInfo.flags)
                        && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                    userId = 0;
                    smap = getServiceMap(0);
                }
                sInfo = new ServiceInfo(sInfo);
                sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
            }
            r = smap.mServicesByName.get(name);
            if (r == null && createIfNeeded) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(service.cloneFilter());
                ServiceRestarter res = new ServiceRestarter();
                BatteryStatsImpl.Uid.Pkg.Serv ss = null;
                BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
                synchronized (stats) {
                    ss = stats.getServiceStatsLocked(
                            sInfo.applicationInfo.uid, sInfo.packageName,
                            sInfo.name);
                }
                // 将查找到的信息组装成ServiceRecord类型
                r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                res.setService(r);
                smap.mServicesByName.put(name, r); // 可以看到分别按照name和filter的形式添加到smap中
                smap.mServicesByIntent.put(filter, r);

                // Make sure this component isn't in the pending list.
                for (int i=mPendingServices.size()-1; i>=0; i--) {
                    ServiceRecord pr = mPendingServices.get(i);
                    if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                            && pr.name.equals(name)) {
                        mPendingServices.remove(i);
                    }
                }
            }
        } catch (RemoteException ex) {
            // pm is in same process, this will never happen.
        }
    }
    // 创建好ServiceRecord后,将其封装成ServiceLookupResult类型返回
    if (r != null) {
        if (mAm.checkComponentPermission(r.permission,
                callingPid, callingUid, r.appInfo.uid, r.exported)
                != PackageManager.PERMISSION_GRANTED) {
            if (!r.exported) {
                return new ServiceLookupResult(null, "not exported from uid "
                        + r.appInfo.uid);
            }
            return new ServiceLookupResult(null, r.permission);
        }
        if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                resolvedType, r.appInfo)) {
            return null;
        }
        return new ServiceLookupResult(r, null);
    }
    return null;
}


  7、ActiveService#startServiceInnerLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
                                      ServiceRecord r, boolean callerFg, boolean addToStarting) {
    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();
    }
    // 使用bringUpServiceLocked来启动ServiceRecord对应的Service组件
    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;
}
    函数继续调用bringUpServiceLocked方法来启动或得到的ServiceRecord所描述的Service组件信息;


8、ActiveServices#bringUpServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) {

    // ====== Service组件启动之前的一系列准备工作 ======//
    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;
    }
    // 当前正在启动Service,所以该ServiceRecord无需再是restart状态
    if (mRestartingServices.remove(r)) {
        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, "REM FR DELAY LIST (bring up): " + r);
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }

    // 确定Service的持有者已经started,否则将不允许开启
    if (mAm.mStartedUsers.get(r.userId) == null) {
        String msg = "Unable to launch app "
                + r.appInfo.packageName + "/"
                + r.appInfo.uid + " for service "
                + r.intent.getIntent() + ": user " + r.userId + " is stopped";
        bringDownServiceLocked(r);
        return msg;
    }

    // Service正在启动,其PMS不可被关闭
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
    }

    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;

    // 获取ServiceRecord对应的Service组件中的android:process属性(manifest中所描述的)
    final String procName = r.processName;
    ProcessRecord app;

    if (!isolated) {
        // 判断Service组件对应的process是否已经存在,已经存在表示该应用程序进程已经启动
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        // 如果存在,则调用realStartServiceLocked方法去开启Service
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (RemoteException e) {
            }
        }
    } else {
        app = r.isolatedProc;
    }

    // 如果Service对应进程不存在,并未启动,则调用startProcessLocked方法去开启
    if (app == null) {
        // @value final ActivityManagerService mAm;
        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";
            bringDownServiceLocked(r);
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }

    // 将ServiceRecord保存到mPendingServices变量中
    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) {
            stopServiceLocked(r);
        }
    }

    return null;
}
    该函数前期做了一系列Service组件启动前的处理工作;后面首先获取Service组件的process属性,即在manifest中定义的android:process属性,获知service组件运行的进程信息;通过getProcessRecordLocked函数,获知process属性对应的进程是否已经运行;如果已经运行,则app不为null,直接调用realStartServiceLocked方法去开启Service;如果Service所要求的进程并未运行,在要调用ActivityManagerService的startProcessLocked方法去开启 。

    这里分情况讨论,先讨论复杂情况,即Service要求在另一个进程中去开启,即process对应的进程未开启;

(一)应用进程未创建情况:

1、ActivityManagerService#startProcessLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
final ProcessRecord startProcessLocked(String processName,
                                       ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                                       String hostingType, ComponentName hostingName, boolean allowWhileBooting,
                                       boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                       boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
                                       boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
                                       String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ProcessRecord app;
    if (!isolated) {
        // 首先检查请求创建的进程是否已经存在
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
    } else {
        // If this is an isolated process, it can't re-use an existing process.
        app = null;
    }
    .......

    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;

    .......

    // 如果应用并未创建
    if (app == null) {
        // 根据processName及uid来创建Progress,newProcessRecordLocked所做的工作就是new ProcessRecord(stats, info, proc, uid);
        // 即创建一个ProcessRecord对象
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            return null;
        }
        app.crashHandler = crashHandler;
        // ProcessRecord创建完毕后,会将该对象添加到mProcessNames中,便于下次查找
        mProcessNames.put(processName, app.uid, app);
        if (isolated) {
            mIsolatedProcesses.put(app.uid, app);
        }
    } else {
        // If this is a new package in the process, add the package to the list
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
    }

    .......
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    return (app.pid != 0) ? app : null;
}
上面代码中的主要工作是首先判断该processName对应的进程是否已经创建且存在,

如果未存在,则调用newProcessRecordLocked方法去出创建;newProcessRecordLocked方法的主要工作就是new ProcessRecord(stats, info, proc, uid);即创建一个ProcessRecord对象;

新创建的ProcessRecord对象添加到mProcessNames中,便于下次查找。

最后调用另一个重载版本startProcessLocked方法去创建进程。


2、ActivityManagerService#startProcessLocked:   

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
private final void startProcessLocked(ProcessRecord app, String hostingType,
                                      String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    .......

    try {
        // ==== 获得待启动的进程的UID与GID ====== //
        int uid = app.uid;
        int[] gids = null;
        .......
        // 调用Process的start方法来启动新进程
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        Process.ProcessStartResult startResult = Process.start(entryPoint,
                app.processName, uid, uid, gids, debugFlags, mountExternal,
                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                app.info.dataDir, entryPointArgs);
        .......
        // 保存Process信息
        app.setPid(startResult.pid);
        app.usingWrapper = startResult.usingWrapper;
        app.removed = false;
        app.killed = false;
        app.killedByAm = false;
        synchronized (mPidsSelfLocked) {
            // 将新启动的进程,以PID为键值将进程信息保存
            this.mPidsSelfLocked.put(startResult.pid, app);
            if (isActivityProcess) {
                /** 这里的启动逻辑是AMS的Handler在PROC_START_TIMEOUT时间后,发送PROC_START_TIMEOUT_MSG消息
                 *  新的应用进程必须在时间内完成启动工作,并向AMS发送启动完成消息,进而AMS可在该进程中启动Service等组件
                 *  否则,AMS将会认为进程启动超时*/
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        }
    } catch (RuntimeException e) {
        ......
    }
}
      主要调用Process的start方法来启动新进程,并将新进程的信息保存到mPidsSelfLocked变量中;

    然后AMS中的Handler会延时发送一个消息,这里的启动逻辑是AMS的Handler在PROC_START_TIMEOUT时间后,发送PROC_START_TIMEOUT_MSG消息;新的应用进程必须在时间内完成启动工作,并向AMS发送启动完成消息,进而AMS可在该进程中启动Service等组件;否则,AMS将会认为进程启动超时。

    来看一下Process的启动过程;进程都是由Zygote创建的,这里来看一下进程的入口函数,start调用时传递的参数:entryPoint = "android.app.ActivityThread",可以看到这里的入口class是ActivityThread。具体的启动函数为ActivityThread的main方法;


3、ActivityThread#main:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
public static void main(String[] args) {

    ......
    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    // 关键在于attach
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    Looper.loop();
}
    创建主线程的Looper,handler消息传递循环环境;然后调用attach方法向AMS发送一个启动完成通知。


4、ActivityThread#attach:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    // 普通进程的情况
    if (!system) {
        .......
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                UserHandle.myUserId());
        // @value final ApplicationThread mAppThread = new ApplicationThread();
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // 获得AMS代理ActivityManagerProxy
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            // 将ApplicationThread对象传递给AMS,AMS就是通过它来与应用进程进行通信的
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
        .....
    } else {
        // 如果是系统进程则直接进行下面创建操作
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            // 创建mInstrumentation及ContextImpl
            mInstrumentation = new Instrumentation();
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            // 创建Application
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            // 调用Application的onCreate
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }
    .....
}
    这里会创建一个ApplicationThread对象mAppThread,mAppThread将会通过attachApplication传递给AMS,AMS通过其来与应用进程进行通信。在attachApplication后,创建Application,调用Application的onCreate,开始生命周期。


5、ActivityManagerNative#ActivityManagerProxy#attachApplication: 

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
}
    传递进来的参数就是mAppThread(ApplicationThread),传递给AMS,消息类型为ATTAH_APPLICATION_TRANSACTION;

由Binder通知机制,来看ActivityManagerNative对IPC消息的处理:


6、ActivityManagerNative#onTransact:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
    }
}
可以看到其具体的处理函数交给子类实现的attachApplication去实现;ActivityManagerService是ActivityManagerNative的子类。


7、ActivityManagerService#attachApplication:

/** @path: \frameworks\base\services\core\java\com\android\server\am\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);
    }
}
继续来看attachAplicationLocked函数;


8、ActivityManagerService#attachAplicationLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
@Override
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
    ProcessRecord app;
    // 获取新创建的应用进程
    if (pid != MY_PID && pid >= 0) { // 应用进程的pid
        synchronized (mPidsSelfLocked) {
            // 在第二步中,mPidsSelfLocked保存了新创建的Process的相关记录数据结构ProcessRecord,这里通过get获取pid对应的ProcessRecord
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }
    ......

    final String processName = app.processName;
    .......
    boolean badApp = false;
    boolean didSomething = false;

    // 可以看到下面根据需要开启Activity和Service
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }

    // 查看该进程是否有需要启动的Services
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }

    // Check if a next-broadcast receiver is in this process...
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            // If the app died trying to launch the receiver we declare it 'bad'
            badApp = true;
        }
    }

    // Check whether the next backup agent is in this process...
    if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
        ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        } catch (Exception e) {
            badApp = true;
        }
    }

    .......

    return true;
}
由前面第二步知,将新创建的进程保存到ActivityManagerService中的mPidsSelfLocked变量中,现在根据关键字PID,将其获取出来,保存到变量app中。

Service组件的相关启动工作在mServices.attachApplicationLocked(app, processName);中完成,该函数会检查是否有Service组件需要进行启动。mServices的类型为ActiveServices;


9、ActiveServices#attachApplicationLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException {
    boolean didSomething = false;
    // 之前在第八步中ActiveServices#bringUpServiceLocked,将待启动的ServiceRecord保存到mPendingServices变量中
    if (mPendingServices.size() > 0) { // 这里判断mPendingServices的大小,确定是否有待启动的Service
        ServiceRecord sr = null;
        try {
            // 遍历所有待启动Service
            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.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                        mAm.mProcessStats);
                // 如方法名所示,这里是真正开启Service的地方
                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;
        }
    }
    // 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 = 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;
}
这里的逻辑其实较为简单,前面一中第8步ActiveServices#bringUpServiceLocked,将待启动的ServiceRecord保存到mPendingServices变量中。这里仅需要判断mPendingServices是否为空,如果不为空,则表示有待启动的Service,然后遍历mPendingServices,对所有的Service(记录Service组件信息的为ServiceRecord)执行realStartServiceLocked,正如方法名所言,这里是真正开启Service的地方。


10、ActiveServices#realStartServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final void realStartServiceLocked(ServiceRecord r,
                                          ProcessRecord app, boolean execInFg) throws RemoteException {
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    // 将待启动的ServiceRecord添加到该进程ProcessRecord的services变量中
    app.services.add(r);
    bumpServiceExecutingLocked(r, execInFg, "create");

    boolean created = false;
    try {
        ........
        // @value IApplicationThread thread;
        // 继续调用IApplicationThread的scheduleCreateService函数
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
    } finally {
        if (!created) {
            app.services.remove(r);
            r.app = null;
            // 启动未成功进行重启
            scheduleServiceRestartLocked(r, false);
            return;
        }
    }
    .......
}
   首先将需要启动的Service组件(ServiceRecord)添加到其所在进程(ProcessRecord)的services变量中;接下来调用app.thread.scheduleCreateService来继续启动Service组件;app.thread是ProcessRecord的IApplicationThread变量,调用IApplicationThread的scheduleCreateService方法;

    这里的app.thread是第一部分第3步ActivityManagerProxy#startService方法中的通过Binder传进去的caller.asBinder(),即Binder代理对象;而caller的实际运行类型为:mMainThread.getApplicationThread()获取的(mMainThread的类型为ActivityThread)。

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
final ApplicationThread mAppThread = new ApplicationThread();
public ApplicationThread getApplicationThread()
{
    return mAppThread;
}
可以看到caller的实际类型为ApplicationThread;

而ApplicationThread继承ApplicationThreadNative:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative
调用asBinder返回的是ApplicationThreadNative自己本身实例;

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public IBinder asBinder()
{
    return this;
}
而在Binder Service代理对象进行处理时:

/** @path: \frameworks\base\core\java\android\app\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();
            // app
            hust.testlearn.View.IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            int userId = data.readInt();
            // 这里调用子类ActivityManagerProxy的startService方法,见第一部分,步骤四
            ComponentName cn = startService(app, service, resolvedType, userId);
            reply.writeNoException();
            ComponentName.writeToParcel(cn, reply);
            return true;
        }
    }
}
可以看到第一部分第4步startService中传进来的参数app(即caller)的实际类型由 ApplicationThreadNative.asInterface(b);来获得。

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative
/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    static public hust.testlearn.View.IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        hust.testlearn.View.IApplicationThread in =
                (hust.testlearn.View.IApplicationThread) obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ApplicationThreadProxy(obj);
    }
}
可以看到app的实际类型为ApplicationThreadProxy;

即前面app.thread的实际类型为ApplicationThreadProxy,下面接着调用ApplicationThreadProxy的scheduleCreateService方法;


11、ApplicationThreadProxy#scheduleCreateService:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public final void scheduleCreateService(IBinder token, ServiceInfo info,
                                        CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(hust.testlearn.View.IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    // 依旧是个IPC,传递消息为SCHEDULE_CREATE_SERVICE_TRANSACTION
    mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}
发送一个 SCHEDULE_CREATE_SERVICE_TRANSACTION IPC通信请求。具体来看其处理函数:


12ApplicationThreadNative#onTransact:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
            data.enforceInterface(hust.testlearn.View.IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            int processState = data.readInt();
            // 调用子类的scheduleCreateService,其子类为ApplicationThread
            scheduleCreateService(token, info, compatInfo, processState);
            return true;
        }
    }
}
    会继续调用子类的ApplicationThread中的scheduleCreateService进行处理。


13、ApplicationThread中#scheduleCreateService:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative {
    final H mH = new H();
    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;

        // 可以看到和启动Activity过程非常相似
        sendMessage(H.CREATE_SERVICE, s);
    }

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
}
可以看到具体的处理逻辑和开启Activity非常相似,通过Handler发送一个 CREATE_SERVICE消息,等待处理;


14、H:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class H extends Handler {
    public static final int CREATE_SERVICE          = 114;
    public void handleMessage(Message msg) {
        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);
                break;
        }
    }

    private void handleCreateService(CreateServiceData data) {

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            // 获得类加载器
            ClassLoader cl = packageInfo.getClassLoader();
            // 通过类加载器创建一个Service实例
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
        }

        try {
            // 创建Context环境
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            // 将service attach到Application中
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            // 调用Service的onCreate开始生命周期
            service.onCreate();
            // 将Service组件添加到mServices变量中
            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) {
        }
    }
}
具体的处理逻辑为通过类加载器创建该组件名对应的Service实例对象,然后创建Context环境与Application(因为该环境下假设是进程未创建的情况),将Service attcah到该环境中;创建完成Service组件之后,调用onCreate,开始Service的生命周期;则整个Service的启动过程完成; 


(二)应用进程已经创建情况:
回到前面第一部分末,来看进程已经创建情况,可以看到如果进程已经创建,则会直接跳过前面步骤,跳到第二部分的第10步ActiveServices#realStartServiceLocked直接向下执行;

你可能感兴趣的:(Service组件的启动机制深入学习)