您的位置:首页 > 其它

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

2016-01-12 10:51 465 查看





一、通过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通信请求。具体来看其处理函数:

12、ApplicationThreadNative#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直接向下执行;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: