本次源碼基于Android11分析
相關(guān)源碼:
/frameworks/base/core/java/android/content/ContextWrapper.java
/frameworks/base/core/java/android/app/ContextImpl.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
/frameworks/base/core/java/android/app/ActivityThread.java
通過bindService
啟動(dòng)的Service,會(huì)執(zhí)行Service的onCreate、onBind罢猪、onUnbind只盹、onDestroy
方法闯第,可以通過onBind方法返回的Binder對(duì)象和調(diào)用端進(jìn)行通信拣宏,并且Service的生命周期和調(diào)用端同步鲫骗。 如下是啟動(dòng)bindService的代碼
var stu: Student? = null
val connection = object : ServiceConnection {
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
stu = Student.Stub.asInterface(p1)
}
override fun onServiceDisconnected(p0: ComponentName?) {
}
}
val intent = Intent(this, Student::class.java)
bindService(intent, connection, BIND_AUTO_CREATE)
如下是bindService的啟動(dòng)流程:
1.bindService 發(fā)起端進(jìn)程
1.1 ContextWrapper.bindService
public class ContextWrapper extends Context {
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
//mBase為ContentImpl
return mBase.bindService(service, conn, flags);
}
}
繼續(xù)調(diào)用ContentImpl.bindService
方法:
class ContextImpl extends Context {
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
final @NonNull LoadedApk mPackageInfo;
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
// 將ServiceConnection轉(zhuǎn)換成Binder對(duì)象變量犬耻,用于進(jìn)程間通信
IServiceConnection sd;
//...
if (mPackageInfo != null) {
// 將ServiceConnection轉(zhuǎn)換成可跨進(jìn)程
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
} else {
throw new RuntimeException("Not supported in system context");
}
validateServiceIntent(service);
try {
//...
// 調(diào)用AMS.bindIsolatedService方法
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
if (res < 0) {
throw new SecurityException(
"Not allowed to bind to service " + service);
}
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
首先將ServiceConnection變量存儲(chǔ)到可跨進(jìn)程通信的Binder對(duì)象并賦值到sd
變量,并把sd
變量傳給AMS中执泰,后續(xù)AMS通過這個(gè)Binder通信枕磁。最后調(diào)用AMS.bindIsolatedService
跨進(jìn)程調(diào)用方法。在分析另一個(gè)AMS進(jìn)程前术吝,先分析本進(jìn)程如何
public final class LoadedApk {
@UnsupportedAppUsage
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
return getServiceDispatcherCommon(c, context, handler, null, flags);
}
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
//...
// 創(chuàng)建ServiceDispatcher對(duì)象计济,并把ServiceConnection參數(shù)作為其變量之一
sd = new ServiceDispatcher(c, context, executor, flags);
//...
// 返回ServiceDispatcher.InnerConnection內(nèi)部類,其繼承IServiceConnection.Stub顿苇,是個(gè)binder
return sd.getIServiceConnection();
}
}
}
static final class ServiceDispatcher {
// 返回的是此對(duì)象
private final ServiceDispatcher.InnerConnection mIServiceConnection;
// 存儲(chǔ)ServiceConnection的變量
private final ServiceConnection mConnection;
private final Context mContext;
private final Handler mActivityThread;
private final Executor mActivityExecutor;
private final ServiceConnectionLeaked mLocation;
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
//創(chuàng)建InnerConnection對(duì)象,等會(huì)會(huì)返回該對(duì)象
mIServiceConnection = new InnerConnection(this);
//用戶定義的ServiceConnection
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mActivityExecutor = null;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
// 返回的是mIServiceConnection變量峭咒,是Binder類
IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
//內(nèi)部的Binder類
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
// 通過構(gòu)造函數(shù)弱引用ServiceDispatcher對(duì)象,此對(duì)象有ServiceConnection變量
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
// 調(diào)用ServiceDispatcher.connected()方法
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}
// ServiceDispatcher.connected()的方法
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
// 在線程池執(zhí)行一個(gè)任務(wù)
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
// 給主線程發(fā)送一個(gè)post一個(gè)任務(wù)
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
// 如果上述兩個(gè)都為空纪岁,則執(zhí)行doConnected方法
doConnected(name, service, dead);
}
}
private final class RunConnection implements Runnable {
RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
mName = name;
mService = service;
mCommand = command;
mDead = dead;
}
public void run() {
if (mCommand == 0) {
// mCommand為0 ,進(jìn)入doConnected方法
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
final ComponentName mName;
final IBinder mService;
final int mCommand;
final boolean mDead;
}
// 調(diào)用ServiceConnection.onServiceConnected()方法
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
if (mForgotten) {
return;
}
old = mActiveConnections.get(name);
if (old != null && old.binder == service) {
return;
}
if (service != null) {
info = new ConnectionInfo();
info.binder = service;
//創(chuàng)建死亡監(jiān)聽對(duì)象
info.deathMonitor = new DeathMonitor(name, service);
try {
//建立死亡通知
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
mActiveConnections.remove(name);
return;
}
} else {
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
// 如果有舊服務(wù)凑队,它現(xiàn)在已斷開連接。
if (old != null) {
mConnection.onServiceDisconnected(name);
}
if (dead) {
mConnection.onBindingDied(name);
}
//如果有新的可行服務(wù)幔翰,它現(xiàn)在已連接漩氨。
if (service != null) {
// 回調(diào)用戶定義的ServiceConnection()
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
}
創(chuàng)建LoadedApk.ServiceDispatcher
類的實(shí)例化對(duì)象,對(duì)象里面包含了一個(gè)Binder對(duì)象LoadedApk.ServiceDispatcher.InnerConnection
,方法最后就是返回這個(gè)Binder對(duì)象遗增。AMS也通過這個(gè)Binder對(duì)象通信調(diào)用ServiceConnection.onServiceConnected()
方法叫惊。
AMS處理bindService請求
首先調(diào)用AMS的bindIsolatedService
方法
public class ActivityManagerService extends IActivityManager.Stub {
final ActiveServices mServices;
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
// 空判斷 ...
// 調(diào)用ActiveServices.bindServiceLocked方法
synchronized (this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
}
AMS方法首先進(jìn)行空判斷,然后調(diào)用ActiveServices
類的bindServiceLocked()
方法:
public final class ActiveServices {
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
//查詢發(fā)起端所對(duì)應(yīng)的進(jìn)程記錄結(jié)構(gòu)
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + callingPid
+ ") when binding service " + service);
}
ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
//token不為空, 代表著發(fā)起方具有activity上下文
if (token != null) {
activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
if (activity == null) {
return 0;
}
}
int clientLabel = 0;
PendingIntent clientIntent = null;
final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
...
//根據(jù)發(fā)送端所在進(jìn)程的SchedGroup來決定是否為前臺(tái)service
final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
// 1. 根據(jù)傳遞進(jìn)來Intent來檢索相對(duì)應(yīng)的服務(wù),service變量就是Intent
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
callingPid, callingUid, userId, true,
callerFg, isBindExternal, allowInstant);
// 空檢查
if (res == null) {
return 0;
}
if (res.record == null) {
return -1;
}
//2. 查詢到相應(yīng)的Service記錄
ServiceRecord s = res.record;
final long origId = Binder.clearCallingIdentity();
try {
// 調(diào)用ServiceRecord.retrieveAppBindingLocked方法
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//創(chuàng)建對(duì)象ConnectionRecord,此處connection來自發(fā)起方
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
IBinder binder = connection.asBinder();
ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<>();
mServiceConnections.put(binder, clist);
}
clist.add(c); // clist是ServiceRecord.connections的成員變量
if ((flags & Context.BIND_AUTO_CREATE) != 0) {
//更新當(dāng)前service活動(dòng)時(shí)間
s.lastActivity = SystemClock.uptimeMillis();
//3. 啟動(dòng)service做修,這個(gè)過程跟startService過程一致
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
//.....
return 1;
}
bindServiceLocked方法主要做了三件事:
- 調(diào)用
retrieveServiceLocked
方法霍狰,根據(jù)Intent解析尋找要啟動(dòng)的Service,并得到ServiceLookupResult對(duì)象實(shí)例饰及。 - 根據(jù)ServiceLookupResult對(duì)象實(shí)例得到
ServiceRecord
對(duì)象蔗坯。 - 調(diào)用
bringUpServiceLocked
方法,開始啟動(dòng)Service燎含。
1. retrieveServiceLocked
根據(jù)Intent解析要啟動(dòng)的ServiceRecord
private ServiceLookupResult retrieveServiceLocked(Intent service,
String instanceName, String resolvedType, String callingPackage,
int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
boolean allowInstant) {
ServiceRecord r = null;
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId,
/* allowAll= */false, getAllowMode(service, callingPackage),
/* name= */ "service", callingPackage);
ServiceMap smap = getServiceMapLocked(userId);
// 1. 根據(jù)Intent獲取全類名
final ComponentName comp;
if (instanceName == null) {
comp = service.getComponent();
} else {
final ComponentName realComp = service.getComponent();
if (realComp == null) {
throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
+ "' without expicit component in Intent");
}
comp = new ComponentName(realComp.getPackageName(),
realComp.getClassName() + ":" + instanceName);
}
// 2. 根據(jù)全類名在緩存中查找相應(yīng)的ServiceRecord
if (comp != null) {
r = smap.mServicesByInstanceName.get(comp);
}
// ServiceRecord為空
if (r == null) {
try {
// 3. 通過PKMS來查詢相應(yīng)的ResolveInfo
ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
resolvedType, flags, userId, callingUid);
ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
return null;
}
//獲取組件名
ComponentName className = new ComponentName(
sInfo.applicationInfo.packageName, sInfo.name);
if (userId > 0) {
//服務(wù)是否屬于單例模式
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
sInfo.name, sInfo.flags)
&& mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
userId = 0;
smap = getServiceMapLocked(0);
}
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
}
r = smap.mServicesByInstanceName.get(name);
if (r == null && createIfNeeded) {
final Intent.FilterComparison filter
= new Intent.FilterComparison(service.cloneFilter());
//創(chuàng)建Restarter對(duì)象
final ServiceRestarter res = new ServiceRestarter();
final BatteryStatsImpl.Uid.Pkg.Serv ss;
final BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
ss = stats.getServiceStatsLocked(
sInfo.applicationInfo.uid, name.getPackageName(),
name.getClassName());
}
// 3.2 創(chuàng)建ServiceRecord對(duì)象
r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
definingUid, filter, sInfo, callingFromFg, res);
r.mRecentCallingPackage = callingPackage;
res.setService(r);
smap.mServicesByInstanceName.put(name, r);
smap.mServicesByIntent.put(filter, r);
//確保該組件不再位于pending隊(duì)列
for (int i = mPendingServices.size() - 1; i >= 0; i--) {
final ServiceRecord pr = mPendingServices.get(i);
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
&& pr.instanceName.equals(name)) {
mPendingServices.remove(i);
}
}
}
} catch (RemoteException ex) {
//運(yùn)行在同一個(gè)進(jìn)程宾濒,不會(huì)發(fā)生RemoteException
}
}
if (r != null) {
//各種權(quán)限檢查,不滿足條件則返回為null的service
//...
//4. 創(chuàng)建Service查詢結(jié)果對(duì)象
return new ServiceLookupResult(r, null);
}
return null;
}
retrieveServiceLocked
方法主要做了四件事:
- 根據(jù)Intent數(shù)據(jù)獲取Service的全類名
- 根據(jù)全類名在緩存查找是否有
ServiceRecord
- 如果緩存中沒有
ServiceRecord
屏箍,則根據(jù)PKMS查找對(duì)應(yīng)的ResolveInfo
,并創(chuàng)建一個(gè)ServiceRecord
對(duì)象 - 最后如果
ServiceRecord
對(duì)象不為空绘梦,則根據(jù)ServiceRecord創(chuàng)建一個(gè)ServiceLookupResult
對(duì)象實(shí)例并返回。
2. bringUpServiceLocked
啟動(dòng)Service
// 啟動(dòng)Service的方法
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
if (r.app != null && r.app.thread != null) {
// 如果service已經(jīng)啟動(dòng)赴魁,那么多次啟動(dòng)Service時(shí)會(huì)多次調(diào)用service.onStartCommand()方法
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && mRestartingServices.contains(r)) {
return null; //等待延遲重啟的過程卸奉,則直接返回
}
// 啟動(dòng)service前,把service從重啟服務(wù)隊(duì)列中移除
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
// service正在啟動(dòng)颖御,將delayed設(shè)置為false
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//確保擁有該服務(wù)的user已經(jīng)啟動(dòng)择卦,否則停止;
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
bringDownServiceLocked(r);
return msg;
}
//服務(wù)正在啟動(dòng),設(shè)置package停止?fàn)顟B(tài)為false
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.packageName + ": " + e);
}
final boolean isolated = (r.serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
if (!isolated) {
// 1. 根據(jù)進(jìn)程名和uid秉继,查詢ProcessRecord
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
// 目標(biāo)進(jìn)程已存在
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
// 2. 調(diào)用realStartServiceLocked方法啟動(dòng)Service
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
}
}
} else {
app = r.isolatedProc;
}
// 對(duì)于進(jìn)程沒有啟動(dòng)的情況
if (app == null && !permissionsReviewRequired) {
// 3. 通過AMS啟動(dòng)service所要運(yùn)行的進(jìn)程
if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
// 進(jìn)程啟動(dòng)失敗
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
r.delayedStop = false;
if (r.startRequested) {
//停止服務(wù)
stopServiceLocked(r);
}
}
return null;
}
bringUpServiceLocked
方法主要做了兩件事:
- 檢查進(jìn)程是否啟動(dòng)祈噪,如果啟動(dòng)了,則調(diào)用
realStartServiceLocked
方法開始真正啟動(dòng)Service尚辑。 - 如果進(jìn)程沒啟動(dòng)辑鲤,則先創(chuàng)建進(jìn)程,進(jìn)程創(chuàng)建完成后才調(diào)用
realStartServiceLocked
方法開始真正啟動(dòng)Service杠茬。
繼續(xù)查看realStartServiceLocked
方法
// 真是啟動(dòng)Service方法
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
//...
// 1. 發(fā)送delay消息月褥,若onCreate方法超時(shí)執(zhí)行未取消,則引發(fā)ANR
bumpServiceExecutingLocked(r, execInFg, "create");
try {
//...
// 2. 通過ApplicationThread調(diào)用Service.onCreate方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
} catch (DeadObjectException e) {
mAm.appDiedLocked(app, "Died when creating service");
throw e;
} finally {
//...
}
// 3. 檢查是否需要執(zhí)行onBind()方法
requestServiceBindingsLocked(r, execInFg);
//...
//4. 服務(wù) 進(jìn)入onStartCommand()
sendServiceArgsLocked(r, execInFg, true);
//...
}
realStartServiceLocked
方法主要做了四件事:
- 調(diào)用
bumpServiceExecutingLocked()
方法發(fā)送一個(gè)延遲消息瓢喉,為Service的onCreate執(zhí)行時(shí)間裝彈宁赤。 - 調(diào)用
app.thread.scheduleCreateService()
方法,通過Service所在進(jìn)程的ApplicationThread
類栓票,去創(chuàng)建Service并調(diào)用Service的onCreate()
方法决左。 - 調(diào)用
requestServiceBindingsLocked()
方法,檢查是否需要執(zhí)行Service的onBind()
方法走贪。 - 調(diào)用
sendServiceArgsLocked()
方法佛猛,檢查是否需要執(zhí)行Service的onStartCommand()
方法
bumpServiceExecutingLocked延遲發(fā)送ANR消息:
static final int SERVICE_TIMEOUT = 20 * 1000;
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
// 發(fā)送一個(gè)延遲消息,消息沒被取消坠狡,則執(zhí)行ANR继找。fg參數(shù)為是否為前臺(tái)Service
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0) {
//...
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
// 發(fā)送Handler
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting++;
r.executingStart = now;
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
//當(dāng)超時(shí)后仍沒有remove該SERVICE_TIMEOUT_MSG消息,則執(zhí)行service Timeout流程
// 在前臺(tái)延遲20s,否則延遲200s
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
如果是前臺(tái)Service則延遲20s發(fā)送ANR消息逃沿,如果是后臺(tái)Service則延遲200s發(fā)送ANR消息婴渡。
requestServiceBindingsLocked檢查是否需要執(zhí)行onBind()方法:
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
// 通過bindService的啟動(dòng)方式,bindings一定不為空
for (int i = r.bindings.size() - 1; i >= 0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
// 1. ANR裝炸彈
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 2. 通過ApplicationThread調(diào)用Service的onBind()方法
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.getReportedProcState());
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
}
//...
}
return true;
}
如果ServiceRecord.bindings
大小>0凯亮,則調(diào)用requestServiceBindingLocked
方法边臼,先通過bumpServiceExecutingLocked
方法給onBind()方法發(fā)送延遲的ANR消息,然后調(diào)用 r.app.thread.scheduleBindService()
方法通過ApplicationThread類調(diào)用Service的onBind()
方法触幼。
sendServiceArgsLocked檢查是否需要執(zhí)行onStartCommand方法
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
ArrayList<ServiceStartArgs> args = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
//...
// 裝彈,延遲發(fā)送一條消息究飞,如果執(zhí)行onStartCommand方法超過
bumpServiceExecutingLocked(r, execInFg, "start");
//...
try {
// 調(diào)用AT.scheduleServiceArgs,最終調(diào)用onStartCommand
r.app.thread.scheduleServiceArgs(r, slice);
}
}
}
如果ServiceRecord.pendingStarts
大小>0則通過r.app.thread.scheduleServiceArgs
調(diào)用Service的onStartCommand
方法置谦。
ActivityThread創(chuàng)建并執(zhí)行Service
由于bindService
啟動(dòng)的Service并不會(huì)執(zhí)行onStartCommand()方法,所以這里只分析onCreate()亿傅、onBind()
方法:
執(zhí)行onCreate()
AMS通過調(diào)用app.thread.scheduleCreateService()
方法去調(diào)用Service的onCreate()
方法的執(zhí)行媒峡。
private class ApplicationThread extends IApplicationThread.Stub {
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;
// 通過Handler發(fā)送消息執(zhí)行
sendMessage(H.CREATE_SERVICE, s);
}
}
public void handleMessage(Message msg) {
switch (msg.what) {
case CREATE_SERVICE:
handleCreateService((CreateServiceData) msg.obj);
break;
}
}
// 創(chuàng)建對(duì)應(yīng)的Service并執(zhí)行onCreate()方法
private void handleCreateService(CreateServiceData data) {
//當(dāng)應(yīng)用處于后臺(tái)即將進(jìn)行GC,而此時(shí)被調(diào)回到活動(dòng)狀態(tài)葵擎,則跳過本次gc
unscheduleGcIdler();
// 1.1 獲取LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 1.2 根據(jù)LoadedApk創(chuàng)建ContextImpl
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
// 2. 創(chuàng)建Application對(duì)象
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 獲取ClassLoader
java.lang.ClassLoader cl = packageInfo.getClassLoader();
// 3. 通過反射創(chuàng)建Service對(duì)象
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
context.setOuterContext(service);
// 4. 調(diào)用service.attach綁定資源文件
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
// 5. 調(diào)用 service.onCreate()方法
service.onCreate();
mServices.put(data.token, service);
try {
// 6. onCreate()執(zhí)行完成谅阿,拆彈過程,最終調(diào)用到ActiveServices.serviceDoneExecutingLocked方法
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
//...
}
}
通過Handler通信,最終會(huì)調(diào)用ActivityThread. handleCreateService
方法签餐,該方法主要6件事:
- 通過
getPackageInfoNoCheck
方法創(chuàng)建一個(gè)LoadedApk
實(shí)例對(duì)象寓涨。并通過LoadedApk對(duì)象創(chuàng)建一個(gè)ContextImpl
對(duì)象。 - 調(diào)用
packageInfo.makeApplication
創(chuàng)建一個(gè)Application
對(duì)象 - 通過反射創(chuàng)建對(duì)應(yīng)的Service實(shí)例對(duì)象
- 調(diào)用
service.attach
方法綁定資源文件 - 調(diào)用
service.onCreate()
方法 - 調(diào)用
ActivityManager.getService().serviceDoneExecuting
向AMS取消延遲發(fā)送的ANR消息氯檐。
執(zhí)行onBind()
AMS通過調(diào)用r.app.thread.scheduleBindService()
方法去執(zhí)行Service的onBind()
方法戒良。
public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
sendMessage(H.BIND_SERVICE, s);
}
}
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_SERVICE:
handleBindService((BindServiceData) msg.obj);
break;
}
}
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
try {
if (!data.rebind) {
// 1. 執(zhí)行Service.onBind()回調(diào)方法
IBinder binder = s.onBind(data.intent);
// 2. 將onBind返回值傳遞回給AMS,
// 讓其回調(diào)ServiceConnection方法冠摄,并取消ANR消息
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
// 取消ANR消息
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
//...
}
}
}
通過Handler通信最終調(diào)用到ActivityThread. handleBindService
方法糯崎,該方法主要做兩件事:
- 調(diào)用
Service.onBind()
方法 - 調(diào)用
ActivityManager.getService().publishService
通過AMS向發(fā)起方的ServiceConnection進(jìn)行回調(diào),并取消ANR的延遲消息河泳。
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ActiveServices mServices;
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized (this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord) token, intent, service);
}
}
}
public final class ActiveServices {
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
if (r != null) {
Intent.FilterComparison filter
= new Intent.FilterComparison(intent);
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i = 0; i < clist.size(); i++) {
ConnectionRecord c = clist.get(i);
try {
//1. 調(diào)用發(fā)起方進(jìn)程的LoadedApk.ServiceDispatcher.InnerConnection.connected方法
c.conn.connected(r.name, service, false);
} catch (Exception e) {
}
}
}
}
// 2. 取消ANR消息
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
最終調(diào)用到ActiveServices.publishServiceLocked()
方法沃呢,向發(fā)起方的進(jìn)行回調(diào),并取消的ANR的延遲消息拆挥。
總結(jié):
bingService
會(huì)執(zhí)行的方法有 onCreate薄霜、onBind、onUnBind竿刁、onDestory
,其中onBind()
方法會(huì)返回一個(gè)Binder
對(duì)象黄锤。
- 發(fā)起方在調(diào)用bingService時(shí)要傳入一個(gè)
ServiceConnection
實(shí)例對(duì)象,并把這個(gè)對(duì)象封裝在一個(gè)Binder對(duì)象中食拜,便于AMS回調(diào)鸵熟。 - AMS則通過
Intent
找到對(duì)應(yīng)的Service記錄,如果Service的進(jìn)程沒啟動(dòng)則先創(chuàng)建進(jìn)程负甸,進(jìn)程啟動(dòng)后依此通過進(jìn)程的ActivityThread
創(chuàng)建并調(diào)用Service的onCreate流强、onBind
方法,并在調(diào)用方法前發(fā)送一個(gè)延遲的ANR消息 - Service進(jìn)程的ActivityThread在
onCreate()
時(shí)先通過反射創(chuàng)建Service呻待,并調(diào)用Service的attach打月、onCreate
方法。在onBind()時(shí)先調(diào)用Service的onBinder
方法蚕捉,并向AMS發(fā)送i個(gè)給發(fā)起方的ServiceConnection
的回調(diào)奏篙。在執(zhí)行完方法后發(fā)送一個(gè)取消執(zhí)行ANR的延遲消息。