client端的startService()
我们在Application或者Activity里调用bindService()的时候,其实调用的是Context中的抽象方法:
public abstract ComponentName startService(Intent service);
复制代码
真正的是现在ContextImpl中:
@Override
public ComponentName startService(Intent service) {
//当system进程调用此方法时输出warn信息,system进程建立调用startServiceAsUser方法
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
复制代码
而startServiceCommon()方法实现如下:
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
//检验service,当service为空则throw异常
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// 调用ActivityManagerNative类
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
复制代码
该方法主要调用AMS.startService(),一些参数,然后通过IPC调用到AMS的startService()方法。
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
//当调用者是孤立进程,则抛出异常。
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
final int callingPid = Binder.getCallingPid();//调用者pid
final int callingUid = Binder.getCallingUid();//调用者uid
final long origId = Binder.clearCallingIdentity();
//此次的mServices为ActiveServices对象
ComponentName res = mServices.startServiceLocked(
caller,//IApplicationThread类型
service,//Intent类型,包含需要运行的service信息
resolvedType,//String类型
callingPid,
callingUid,
callingPackage,//String类型,调用该方法的package
userId//用户的id
);
Binder.restoreCallingIdentity(origId);
return res;
}
}
复制代码
mServices是ActiveServices对象,其bindServiceLocked()方法如下:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
final boolean callerFg;
if (caller != null) {
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//检索服务信息
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
ServiceRecord r = res.record;
//检查是否存在启动服务的user
if (!mAm.mUserController.exists(r.userId)) {
Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
return null;
}
if (!r.startRequested) {
final long token = Binder.clearCallingIdentity();
try {
// Before going further -- if this app is not allowed to run in the
// background, then at this point we aren't going to let it period. final int allowed = mAm.checkAllowBackgroundLocked( r.appInfo.uid, r.packageName, callingPid, true); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { Slog.w(TAG, "Background start not allowed: service " + service + " to " + r.name.flattenToShortString() + " from pid=" + callingPid + " uid=" + callingUid + " pkg=" + callingPackage); return null; } } finally { Binder.restoreCallingIdentity(token); } } NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked( callingUid, r.packageName, service, service.getFlags(), null, r.userId); // If permissions need a review before any of the app components can run, // we do not start the service and launch a review activity if the calling app // is in the foreground passing it a pending intent to start the service when // review is completed. if (Build.PERMISSIONS_REVIEW_REQUIRED) { if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage, callingUid, service, callerFg, userId)) { return null; } } if (unscheduleServiceRestartLocked(r, callingUid, false)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r); } r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true; r.delayedStop = false; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants)); final ServiceMap smap = getServiceMap(r.userId); boolean addToStarting = false; //对于非前台进程的调度 if (!callerFg && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) { ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false); if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) { // If this is not coming from a foreground caller, then we may want // to delay the start if there are already other background services // that are starting. This is to avoid process start spam when lots // of applications are all handling things like connectivity broadcasts. // We only do this for cached processes, because otherwise an application // can have assumptions about calling startService() for a service to run // in its own process, and for that process to not be killed before the // service is started. This is especially the case for receivers, which // may start a service in onReceive() to do some additional work and have // initialized some global state as part of that. if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of " + r + " in " + proc); if (r.delayed) {//已计划延迟启动 // This service is already scheduled for a delayed start; just leave // it still waiting. if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r); return r.name; } if (smap.mStartingBackground.size() >= mMaxStartingBackground) { // Something else is starting, delay! Slog.i(TAG_SERVICE, "Delaying start of: " + r); //当超出 同一时间允许后续启动的最大服务数,则将该服务加入延迟启动的队列。 smap.mDelayedStartList.add(r); r.delayed = true; return r.name; } if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r); addToStarting = true; } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) { // We slightly loosen when we will enqueue this new service as a background // starting service we are waiting for, to also include processes that are // currently running other services or receivers. //将新的服务加入到后台启动队列,该队列也包含当前正在运行其他services或者receivers的进程 addToStarting = true; if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying, but counting as bg: " + r); } else if (DEBUG_DELAYED_STARTS) { StringBuilder sb = new StringBuilder(128); sb.append("Not potential delay (state=").append(proc.curProcState) .append(' ').append(proc.adjType); String reason = proc.makeAdjReason(); if (reason != null) { sb.append(' '); sb.append(reason); } sb.append("): "); sb.append(r.toString()); Slog.v(TAG_SERVICE, sb.toString()); } } else if (DEBUG_DELAYED_STARTS) { //当发起方进程不等于Process.THREAD_GROUP_BG_NONINTERACTIVE,或者发起方为空, 则callerFg= true; //否则,callerFg= false; if (callerFg) { Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid=" + callingUid + " pid=" + callingPid + "): " + r); } else if (r.app != null) { Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r); } else { Slog.v(TAG_SERVICE, "Not potential delay (user " + r.userId + " not started): " + r); } } return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); } 复制代码
该方法主要包括了:
- 调用retrieveServiceLocked()方法来获取ServiceLookupResult这个查询结果,这个方法会先尝试从缓存中取出ServiceRecord对象,如果没有则新建ServiceRecord并且存入缓存中,最后返回的ServiceLookupResult是ServiceRecord的包装类;
- 调用unscheduleServiceRestartLocked(),即如果要启动的Service在重启名单中,那么就将它从AMS的mHandler中移除重启的Callback;
- 调用startServiceInnerLocked()将启动Service,这个过程还可能伴随启动Service所在进程(如果进程没有启动的话);
startServiceInnerLocked()如下:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();//用于耗电统计,开启运行的状态
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStarts();
}
} else if (callerFg) {
smap.ensureNotStartingBackground(r);
}
return r.name;
}
复制代码
service端进程启动以及service启动
可以参考bindService()。
启动service
service所在进程已经启动
如果需要启动的service已经启动
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;
sendMessage(H.SERVICE_ARGS, s);
}
复制代码
在Handler里处理:
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
复制代码
这里就调用到了service的onStartCommand()方法。
如果需要启动的service还没有已经启动
首先创建service
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
if (DEBUG_MU)
Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
+ ", ProcessRecord.uid = " + app.uid);
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
//发送delay消息
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
boolean created = false;
try {
if (LOG_SERVICE_START_STOP) {
String nameTerm;
int lastPeriod = r.shortName.lastIndexOf('.');
nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
EventLogTags.writeAmCreateService(
r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
}
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//服务进入 onCreate()
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
//应用死亡处理
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
app.services.remove(r);
r.app = null;
}
// Retry.
//尝试重新启动服务
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
//服务 进入onStartCommand()
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop! r.delayedStop = false; if (r.startRequested) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Applying delayed stop (from start): " + r); stopServiceLocked(r); //停止服务 } } } 复制代码
方法中主要做了,创建service并调用onCreate()方法,绑定服务,调用service的onStartCommand()方法。
service所在进程还没启动
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
...
//省略前两种情况了,已经分析过
if (app == null) {
//没有加载过这个进程,创建一个新的进程,然后启动service
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
//启动service,一会分析
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//保存这个ServiceRecord
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
....
return null;
}
复制代码
上面判断如果需要创建进程的话是通过调用mAm.startProcessLocked生成了进程,mAm就是AMS,我们直接看startProcessLocked方法:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
.....
try {
.....
//注意看如果entryPoint等于null的话,会被赋值android.app.ActivityThread
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
checkTime(startTime, "startProcess: asking zygote to start proc");
//启动进程
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);
checkTime(startTime, "startProcess: returned from zygote!");
....
} catch (RuntimeException e) {
.....
}
}
复制代码
指定了ActivityThread的这个类后,在创建进程完成后会调用ActivityThread的main方法。进程启动过程中会回调
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
//启动mPendingServices队列中,等待在该进程启动的服务
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
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
proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
mAm.mProcessStats);
// 启动服务,即将进入服务的生命周期
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
if (!isServiceNeeded(sr, false, false)) {
// We were waiting for this service to start, but it is actually no
// longer needed. This could happen because bringDownServiceIfNeeded
// won't bring down a service that is pending... so now the pending // is done, so let's drop it.
bringDownServiceLocked(sr);
}
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting service "
+ sr.shortName, e);
throw e;
}
}
// Also, if there are any services that are waiting to restart and
// would run in this process, now is a good time to start them. It would
// be weird to bring up the process but arbitrarily not let the services
// run at this point just because their restart time hasn't come up. // 对于正在等待重启并需要运行在该进程的服务,现在是启动它们的大好时机 if (mRestartingServices.size() > 0) { ServiceRecord sr; for (int i=0; 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; } 复制代码
这边回到了就是service没有启动,但是service所在进程已经存在的情况。
创建service
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
//LoadedApk是LoadedApk对象是APK文件在内存中的表示。
//Apk文件的相关信息,诸如Apk文件的代码和资源,
//甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取。
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//加载service类
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//判断Application是否创建,没有创建会创建Application对象,
//但是在上面创建进程的时候已经创建,所以会直接返回
Application app = packageInfo.makeApplication(false, mInstrumentation);
//初始化service
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//调用service的 onCreate方法
service.onCreate();
//存储service的信息
mServices.put(data.token, service);
try {
//通知AMS已经创建完毕
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
复制代码
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101620.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...