一、通過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;
}
/** @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方法去創建進程。
/** @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的啓動過程完成;