您的位置:首页 > 移动开发 > Android开发

Service的工作过程 基于Android O(8.0) API 27

2018-01-24 20:32 417 查看
Service的工作过程

本文是《Android开发艺术探索》第9章学习笔记

启动Service

Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);


ContextWrapper

ContextWrapper#startService

@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}


mBase为Context类型,实现是ContextImpl;

ContextImpl

ContextImpl#startService

在ContextImpl中startService回调用
startServiceCommon(service, false, mUser)


@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}


ContextImpl#startServiceCommonstartServiceCommon

在 startServiceCommon中通过ActivityManager.getService对象(AMS)来启动一个服务。

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
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());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}


ActivityManagerService

ActivityManagerService

具体实现是在ActivityManagerService

ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
boolean fgRequired, String callingPackage, int userId)
throws TransactionTooLargeException {
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(null, service,
resolvedType, -1, uid, fgRequired, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}


在上述代码中AMS会
mServices.startServiceLocked
来调用,其中mServices为ActiveServices类型,来进行Service的管理,包括启动、绑定和停止等。

ActiveServices#startServiceLocked

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
...
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}


在最后会调用startServiceInnerLocked方法

ActiveServices#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);
}
...
return r.name;
}


在方法中会调用bringUpServiceLocked方法.对于ServiceRecord :用来描述Service组件当一个应用程序进程绑定了一个Service组件之后,用来描述这个应用程序进程的一个ProcessRecord对象就会被保存在用来描述这个被绑定的Service组件的一个ServiceRecord对象的成员变量bindings中,由于一个Service组件可能会被多个应用程序绑定,因此,用来描述这个Service

ActiveServices#performServiceRestartLocked

final void performServiceRestartLocked(ServiceRecord r) {
if (!mRestartingServices.contains(r)) {
return;
}
...
try {
bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
} catch (TransactionTooLargeException e) {
// Ignore, it's been logged and nothing upstack cares.
}
}


ActiveServices#bringUpServiceLocked

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//Slog.i(TAG, "Bring up service:");
//r.dump("  ");
...
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;

if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}

// If a dead object exception was thrown -- fall through to
// restart the application.
}
}
return null;
}


其中
realStartServiceLocked(r, app, execInFg);
为关键代码

ActiveServices#realStartServiceLocked

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);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
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);
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, 0));
}

sendServiceArgsLocked(r, execInFg, true);

if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
getServiceMapLocked(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);
}
}
}


realStartServiceLocked
方法中以下几步比较重要

- app.thread.scheduleCreateService 通过该方法创建并调用其app.thread是IApplicationThread类型,它实际上是一个Binder,它的具体实现是ActivityThread

- 通过sendServiceArgsLocked方法来调用Service的其它方法,如onStartCommand

ActivityThread

ActivityThread#scheduleCreateService

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);
}


这个和Activity的启动过程十分类似,通过
sendMessage(H.CREATE_SERVICE, s);
来启动Serivice

ActivityThread$H

private class H extends Handler {
public static final int LAUNCH_ACTIVITY         = 100;
public static final int PAUSE_ACTIVITY          = 101;
public static final int PAUSE_ACTIVITY_FINISHING= 102;
public static final int STOP_ACTIVITY_SHOW      = 103;
public static final int STOP_ACTIVITY_HIDE      = 104;
public static final int SHOW_WINDOW             = 105;
public static final int HIDE_WINDOW             = 106;
public static final int RESUME_ACTIVITY         = 107;
public static final int SEND_RESULT             = 108;
public static final int DESTROY_ACTIVITY        = 109;
public static final int BIND_APPLICATION        = 110;
public static final int EXIT_APPLICATION        = 111;
public static final int NEW_INTENT              = 112;
public static final int RECEIVER                = 113;
public static final int CREATE_SERVICE          = 114;
public static final int SERVICE_ARGS            = 115;
public static final int STOP_SERVICE            = 116;

public static final int CONFIGURATION_CHANGED   = 118;
public static final int CLEAN_UP_CONTEXT        = 119;
public static final int GC_WHEN_IDLE            = 120;
public static final int BIND_SERVICE            = 121;
public static final int UNBIND_SERVICE          = 122;
public static final int DUMP_SERVICE            = 123;
public static final int LOW_MEMORY              = 124;
public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
public static final int RELAUNCH_ACTIVITY       = 126;
public static final int PROFILER_CONTROL        = 127;
public static final int CREATE_BACKUP_AGENT     = 128;
public static final int DESTROY_BACKUP_AGENT    = 129;
public static final int SUICIDE                 = 130;
public static final int REMOVE_PROVIDER         = 131;
public static final int ENABLE_JIT              = 132;
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
public static final int SCHEDULE_CRASH          = 134;
public static final int DUMP_HEAP               = 135;
public static final int DUMP_ACTIVITY           = 136;
public static final int SLEEPING                = 137;
public static final int SET_CORE_SETTINGS       = 138;
public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
public static final int TRIM_MEMORY             = 140;
public static final int DUMP_PROVIDER           = 141;
public static final int UNSTABLE_PROVIDER_DIED  = 142;
public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
public static final int INSTALL_PROVIDER        = 145;
public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
public static final int CANCEL_VISIBLE_BEHIND = 147;
public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
public static final int ENTER_ANIMATION_COMPLETE = 149;
public static final int START_BINDER_TRACKING = 150;
public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
public static final int MULTI_WINDOW_MODE_CHANGED = 152;
public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
public static final int ATTACH_AGENT = 155;
public static final int APPLICATION_INFO_CHANGED = 156;
public static final int ACTIVITY_MOVED_TO_DISPLAY = 157;

String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
case SHOW_WINDOW: return "SHOW_WINDOW";
case HIDE_WINDOW: return "HIDE_WINDOW";
case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
case SEND_RESULT: return "SEND_RESULT";
case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
case BIND_APPLICATION: return "BIND_APPLICATION";
case EXIT_APPLICATION: return "EXIT_APPLICATION";
case NEW_INTENT: return "NEW_INTENT";
case RECEIVER: return "RECEIVER";
case CREATE_SERVICE: return "CREATE_SERVICE";
case SERVICE_ARGS: return "SERVICE_ARGS";
case STOP_SERVICE: return "STOP_SERVICE";
case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
case BIND_SERVICE: return "BIND_SERVICE";
case UNBIND_SERVICE: return "UNBIND_SERVICE";
case DUMP_SERVICE: return "DUMP_SERVICE";
case LOW_MEMORY: return "LOW_MEMORY";
case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
case ACTIVITY_MOVED_TO_DISPLAY: return "ACTIVITY_MOVED_TO_DISPLAY";
case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
case PROFILER_CONTROL: return "PROFILER_CONTROL";
case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
case SUICIDE: return "SUICIDE";
case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
case ENABLE_JIT: return "ENABLE_JIT";
case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
case DUMP_HEAP: return "DUMP_HEAP";
case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
case SLEEPING: return "SLEEPING";
case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
case TRIM_MEMORY: return "TRIM_MEMORY";
case DUMP_PROVIDER: return "DUMP_PROVIDER";
case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
case ATTACH_AGENT: return "ATTACH_AGENT";
case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED";
}
}
return Integer.toString(code);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY_FINISHING: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case STOP_ACTIVITY_SHOW: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
SomeArgs args = (SomeArgs) msg.obj;
handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case STOP_ACTIVITY_HIDE: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
SomeArgs args = (SomeArgs) msg.obj;
handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case SHOW_WINDOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
handleWindowVisibility((IBinder)msg.obj, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case HIDE_WINDOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
handleWindowVisibility((IBinder)msg.obj, false);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case RESUME_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
SomeArgs args = (SomeArgs) msg.obj;
handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
args.argi3, "RESUME_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SEND_RESULT:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
handleSendResult((ResultData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case DESTROY_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
msg.arg2, false);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
case NEW_INTENT:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
handleNewIntent((NewIntentData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
handleReceiver((ReceiverData)msg.obj);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case STOP_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
handleStopService((IBinder)msg.obj);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CONFIGURATION_CHANGED:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
mUpdatingSystemConfig = true;
try {
handleConfigurationChanged((Configuration) msg.obj, null);
} finally {
mUpdatingSystemConfig = false;
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CLEAN_UP_CONTEXT:
ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
cci.context.performFinalCleanup(cci.who, cci.what);
break;
case GC_WHEN_IDLE:
scheduleGcIdler();
break;
case DUMP_SERVICE:
handleDumpService((DumpComponentInfo)msg.obj);
break;
case LOW_MEMORY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
handleLowMemory();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case ACTIVITY_CONFIGURATION_CHANGED:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
INVALID_DISPLAY);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case ACTIVITY_MOVED_TO_DISPLAY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
msg.arg1 /* displayId */);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case PROFILER_CONTROL:
handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
break;
case CREATE_BACKUP_AGENT:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case DESTROY_BACKUP_AGENT:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SUICIDE:
Process.killProcess(Process.myPid());
break;
case REMOVE_PROVIDER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
completeRemoveProvider((ProviderRefCount)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case ENABLE_JIT:
ensureJitEnabled();
break;
case DISPATCH_PACKAGE_BROADCAST:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SCHEDULE_CRASH:
throw new RemoteServiceException((String)msg.obj);
case DUMP_HEAP:
handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
break;
case DUMP_ACTIVITY:
handleDumpActivity((DumpComponentInfo)msg.obj);
break;
case DUMP_PROVIDER:
handleDumpProvider((DumpComponentInfo)msg.obj);
break;
case SLEEPING:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SET_CORE_SETTINGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
handleSetCoreSettings((Bundle) msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case UPDATE_PACKAGE_COMPATIBILITY_INFO:
handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
break;
case TRIM_MEMORY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
handleTrimMemory(msg.arg1);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case UNSTABLE_PROVIDER_DIED:
handleUnstableProviderDied((IBinder)msg.obj, false);
break;
case REQUEST_ASSIST_CONTEXT_EXTRAS:
handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
break;
case TRANSLUCENT_CONVERSION_COMPLETE:
handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
break;
case INSTALL_PROVIDER:
handleInstallProvider((ProviderInfo) msg.obj);
break;
case ON_NEW_ACTIVITY_OPTIONS:
Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
onNewActivityOptions(pair.first, pair.second);
break;
case CANCEL_VISIBLE_BEHIND:
handleCancelVisibleBehind((IBinder) msg.obj);
break;
case BACKGROUND_VISIBLE_BEHIND_CHANGED:
handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
break;
case ENTER_ANIMATION_COMPLETE:
handleEnterAnimationComplete((IBinder) msg.obj);
break;
case START_BINDER_TRACKING:
handleStartBinderTracking();
break;
case STOP_BINDER_TRACKING_AND_DUMP:
handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
break;
case MULTI_WINDOW_MODE_CHANGED:
handleMultiWindowModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
((SomeArgs) msg.obj).argi1 == 1,
(Configuration) ((SomeArgs) msg.obj).arg2);
break;
case PICTURE_IN_PICTURE_MODE_CHANGED:
handlePictureInPictureModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
((SomeArgs) msg.obj).argi1 == 1,
(Configuration) ((SomeArgs) msg.obj).arg2);
break;
case LOCAL_VOICE_INTERACTION_STARTED:
handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
(IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
break;
case ATTACH_AGENT:
handleAttachAgent((String) msg.obj);
break;
case APPLICATION_INFO_CHANGED:
mUpdatingSystemConfig = true;
try {
handleApplicationInfoChanged((ApplicationInfo) msg.obj);
} finally {
mUpdatingSystemConfig = false;
}
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}

private void maybeSnapshot() {
if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
// convert the *private* ActivityThread.PackageInfo to *public* known
// android.content.pm.PackageInfo
String packageName = mBoundApplication.info.mPackageName;
android.content.pm.PackageInfo packageInfo = null;
try {
Context context = getSystemContext();
if(context == null) {
Log.e(TAG, "cannot get a valid context");
return;
}
PackageManager pm = context.getPackageManager();
if(pm == null) {
Log.e(TAG, "cannot get a valid PackageManager");
return;
}
packageInfo = pm.getPackageInfo(
packageName, PackageManager.GET_ACTIVITIES);
} catch (NameNotFoundException e) {
Log.e(TAG, "cannot get package info for " + packageName, e);
}
SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
}
}
}


在H中
case CREATE_SERVICE:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));

handleCreateService((CreateServiceData)msg.obj);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);


通过handleCreateService来处理,其中CreateServiceData 对象所描述的是一个Ashmem中的Service

ActivityThread#handleCreateService

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 packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//1.通过类加载器创建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 {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//2.创建Application对象,并调用其onCreate
Application app = packageInfo.makeApplication(false, mInstrumentation);
//3.通过Service的attach,和ContextImpl建立联系
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//4.调用 Service的onCreate方法,并将Service放入到mServices中
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}


handleCreateService主要完成下面几件事情:

- 通过类加载器创建Service的实例

- 调用 Service的onCreate方法,并将Service放入到mServices中

- 通过Service的attach,和ContextImpl建立联系

- 调用Service的onCreate方法,并将Service放入到mServices中

此外,ActivityThread中还会通过handleServiceArgs方法来调用Service的onStartCommand方法

ActivityThread#handleServiceArgs

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 {
ActivityManager.getService().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

Intent bindIntent = new Intent(this, ProxyService.class);
//          BIND_AUTO_CREATE 表示活动和服务进行绑定后自动创建服务。
bindService(bindIntent, connection, BIND_AUTO_CREATE)


接着会调用ContextWrapper的bindService方法

ContextWrapper

ContextWrapper#bindService

@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}


具体实现是在ContextImpl的bindService

ContextImpl

ContextImpl#bindService

@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}


接着调用bindServiceCommon方法

ContextImpl#bindServiceCommon

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else {
throw new RuntimeException("Not supported in system context");
}
validateServiceIntent(service);
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess(this);
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, 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();
}
}


bindServiceCommon主要完成下面几个内容:

1. 将
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
ServiceConnection对象转化为ServiceDispatcher.InnerContection对象,之所以不能直接使用ServiceConnection是因为Service的绑定有可能是跨进程的。InnerConnection用来连接一个Service组件和一个Activity,并且与这个Activity 组件运行在同一个程序的进程中。

LoadedApk#getServiceDispatcher

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
sd = map.get(c);
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}


上述代码中
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices= new ArrayMap<>();


mServices是一个ArrayMap,它存储了一个应用当前活动的ServiceConnection和ServiceDispatcher的映射关系。系统首先会找是否存在相同的ServiceConnection,如果不存在就创建一个ServiceDispatcher,并将其存储在mServices中,其中映射关系的key是ServiceConnection,value是ServiceDispatcher,在ServiceDispatcher内部又保存了ServiceConnection和InnerConnection对象。当Service和客户端建立连接后,系统会通过InnerConnection 来调用ServiceConnection的onServiceConnected方法,这个过程有可能是跨进程的。当ServiceDispatcher创建好之后,getServiceDispatcher会返回其保存的InnerConnection对象。

-

这段代码最为关键
int res = ActivityManager.getService().bindService(

mMainThread.getApplicationThread(), getActivityToken(), service,

service.resolveTypeIfNeeded(getContentResolver()),

sd, flags, getOpPackageName(), user.getIdentifier());


ActivityManagerService

ActivityManagerService#bindService

public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");

// 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");
}

synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}


接下来会调用ActiveServices的bindServiceLocked

ActiveServices

ActiveServices#bindServiceLocked

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {

try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
callerFg, false, false);

return 1;
}


ActiveServices#bringUpServiceLocked

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
...
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
...
return null;
}


ActiveServices#realStartServiceLocked

private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
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;
}
...
}


关键代码:
app.thread.scheduleCreateService(r, r.serviceInfo,                 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),

app.repProcState);


具体实现在

ActivityThread

ActivityThread#scheduleCreateService

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);
}


通过H的
sendMessage(H.CREATE_SERVICE, s);


case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;


交个ActivityThread的handleBindService处理

ActivityThread#handleBindService

private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}


Service有一个特性,多次绑定同一个Service时,Service的onBind方法只会执行一次,除非Service终止了。当Service的onBind方法执行以后,系统还会告知客户端已经成功连接Service了。这个过程由publishService方法来实现

ActivityManagerService#publishService

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);
}
}


又调用##ActivityManagerService#publishServiceLocked

ActiveServices#publishServiceLocked

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
+ " " + intent + ": " + service);
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;
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent)) {
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Not publishing to: " + c);
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Published intent: " + intent);
continue;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
try {
c.conn.connected(r.name, service, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + r.name +
" to connection " + c.conn.asBinder() +
" (in " + c.binding.client.processName + ")", e);
}
}
}
}

serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}


关键代码: c.conn.connected(r.name, service, false); 其中 c为 ConnectionRecord,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: