注册

Android知识点之Service(一)


1、service 启动流程(Android 11)

(1)、启动服务流程(同进程)

a、应用内调用到AMS过程

在Activity环境下调用startService方法 frameworks/base/core/java/android/content/ContextWrapper.java

public ComponentName startService(Intent service) {
//mBase就是Activity在启动时在ActivityThread中创建的ContextImpl.java对象
return mBase.startService(service);
}

frameworks/base/core/java/android/app/ContextImpl.java

public ComponentName startService(Intent service) {
····
return startServiceCommon(service, false, mUser);
}

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
····
//通过Binder机制跨进程调用AMS的startService方法
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
····
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

frameworks/base/core/java/android/app/ActivityManager.java

public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}

@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//IActivityManager是Binder机制实现接口类
//ServiceManager是缓存Binder的实现对象,通过getService()可以获取到跨进程通信的Binder实现对象
//例如WMS、PMS等都可以通过这个ServiceManager对象获取到
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

至此,启动服务就进入了SystemServer进程继续工作

b、AMS处理以及调用ActivityThread过程

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
····
synchronized(this) {
···
ComponentName res;
try {
//mServices对应的是ActiveServices.java对象
//caller为ActivityThread中的ApplicationThread的Binder机制实现类,用于与应用进程通信
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
}
····
return res;
}
}

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false);
}

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
····
//一切准备就绪,调用此处来启动服务
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
····
return cmp;
}

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
····
//启动服务
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
····
return r.name;
}

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
····
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
····
ProcessRecord app;
//判断启动的服务进程是否存在
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
···
if (app != null && app.thread != null) {
try {
····
//存在则直接启动服务
realStartServiceLocked(r, app, execInFg);
return null;
}
···
}
} else {
//启动的服务进程不存在,需要创建HostingRecord辅助开启创建进程
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
r.definingUid);
}
}
//启动的服务进程不存在,创建一个新的进程
if (app == null && !permissionsReviewRequired) {
//启动一个新进程
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
····
}
····
}
····
return null;
}

private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
····
//启动ANR弹窗任务,当启动前台服务超过20s或者后台服务超过200s时,会弹ANR系统窗口提示应用无响应
bumpServiceExecutingLocked(r, execInFg, "create");
····
try {
····
//跨进程调用应用ActivityThread对象,进而调用service的onCreate生命周期方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
····
created = true;
} catch (DeadObjectException e) {
····
} finally {
//启动出现异常,那么ANR弹窗任务需要移除掉
if (!created) {
····
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
····
}
}
//跨进程调用应用ActivityThread对象,进而调用service的onStartCommand生命周期方法
//绑定服务在这个方法中会限制调用,不会调用service的onStartCommand生命周期方法
sendServiceArgsLocked(r, execInFg, true);
····
}

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
····
while (r.pendingStarts.size() > 0) {
···
//启动ANR弹窗任务,当启动前台服务超过20s或者后台服务超过200s时,会弹ANR系统窗口提示应用无响应
bumpServiceExecutingLocked(r, execInFg, "start");
···
}
····
try {
//通过跨进程调用应用进程的ActivityThread的ApplicationThread中的scheduleServiceArgs启动服务
r.app.thread.scheduleServiceArgs(r, slice);
} catch (TransactionTooLargeException e) {
···
caughtException = e;
} catch (RemoteException e) {
····
caughtException = e;
} catch (Exception e) {
····
caughtException = e;
}
if (caughtException != null) {
···
for (int i = 0; i < args.size(); i++) {
//启动出现异常,那么ANR弹窗任务需要移除掉
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
···
}
}

service启动在SystemServer进程需要判断是否需要创建新进程,还需要监测service启动的超时时间,除此之后还需要判断权限等等,最终通过Binder机制调用应用进程方法调用service生命周期方法

c、应用ActivityThread处理过程

service的onCreate生命周期方法流程 frameworks/base/core/java/android/app/ActivityThread.java

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;
//向主线程发送一条消息
sendMessage(H.CREATE_SERVICE, s);
}

class H extends Handler {
public void handleMessage(Message msg) {
····
switch (msg.what) {
····
case CREATE_SERVICE:
····
//主线程处理Server启动
handleCreateService((CreateServiceData) msg.obj);
····
break;
····
}
}
}

private void handleCreateService(CreateServiceData data) {
····
try {
····
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Server生命周期方法
service.onCreate();
····
try {
//调用AMS的serviceDoneExecuting方法移除Server超时监测任务
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
····
}
}

service的onStartCommand生命周期方法流程 frameworks/base/core/java/android/app/ActivityThread.java

public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
//向主线程发送一条消息
sendMessage(H.SERVICE_ARGS, s);
}
}

class H extends Handler {
public void handleMessage(Message msg) {
····
switch (msg.what) {
····
case SERVICE_ARGS:
····
//处理服务启动
handleServiceArgs((ServiceArgsData) msg.obj);
····
break;
····
}
}
}

private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
····
if (!data.taskRemoved) {
//调用service的onStartCommand生命周期方法
res = s.onStartCommand(data.args, data.flags, data.startId);
}
····
try {
//跨进程调用AMS方法将ANR任务移除
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
}
···
} catch (Exception e) {
····
}
}
}

0 个评论

要回复文章请先登录注册