赞
踩
在Activity中使用startService启动Service时,会调用ContextWrapper的startService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/content/ContextWrapper.java
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
这个方法的mBase就是一个ContextImpl类型的对象。所以这里调用了ContextImpl类的startService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.java @Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); //注意传入的第二个参数是 false ,表示启动的服务不是前台服务 return startServiceCommon(service, false, mUser); } private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) { try { // Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常 validateServiceIntent(service); service.prepareToLeaveProcess(this); //关键代码 ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier()); // ... return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
这个方法内部通过先调用validateServiceIntent方法进行Intent检查,Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常,接着调用 ActivityManager.getService()获取到了ActivityManagerService(后面简称AMS)在app进程的代理对象,并调用了这个代理对象的startService方法,下面看看AMS中的startService方法的具体实现:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java @Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // ... synchronized(this) { // ... ComponentName res; try { // 关键代码 res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, userId); } finally { Binder.restoreCallingIdentity(origId); } return res; } }
这个方法内部通过mServices.startServiceLocked方法,mServices是ActiveServices类型的,所以调用了ActiveServices类的startServiceLocked方法,下面看看这个方法具体实现:
http://androidxref.com/9.0.0_r3/xref/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, final int userId) 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 { //... if (app == null && !permissionsReviewRequired) { // 关键代码 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingType, r.name, false, isolated, false)) == null) { String msg = "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " + r.intent.getIntent() + ": process is bad"; bringDownServiceLocked(r); return msg; } // ... } // ... return null; }
这个方法中的mAm.startProcessLocked(),mAm这个变量是AMS,代码跳转到AMS类中执行,下面看看这个方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
接着调用了startProcessLocked的几个重载方法后,最终调用了startProcess方法,startProcess方法内部会调用Process类的start方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/Process.java public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); }
这个方法内部又调用了ZygoteProcess类的start方法。这个过程是SystemServer进程和ZygoteProcess进程进行通信的过程,它们之间通信是通过Socket进行通信的。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/ZygoteProcess.java public final Process.ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); throw new RuntimeException( "Starting VM process through Zygote failed", ex); } } private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<String>(); // ... synchronized(mLock) { //关键代码 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } }
zygoteSendArgsAndGetResult方法创建一个App进程。至此,app进程总算创建完成。接着会执行app进程的ActivityThread的main方法。这个main方法是app进程的入口。下面看看ActivityThread类的main方法。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java public static void main(String[] args) { // ... Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); // ... ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // ... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
这个方法内部, 主要是准备一个Looper对象,并准备一个消息列表,用于存在主线程的handler发送的消息。并创建一个ActivityThread对象。并调用attach方法,并且,如果sMainThreadHandler为null,给sMainThreadHandler赋值,
并且调用Looper.loop方法循环到从消息队列中抽取消息。下面来看看attach方法的具体实现:
private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { // ... final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq); } // ... } else { // ... } // ... }
这个方法中,获取了ActivityManagerServcie在app客户端的代理对象,调用代理对象的attachApplication方法,这时,app进程挂起,SystemServer进程的AMS类的attachApplication方法执行。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java @Override public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { // ... //关键代码 attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); } } @GuardedBy("this") private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { // ... try { // ... if (app.isolatedEntryPoint != null) { thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } // ... } // ... // Find any services that should be running in this process... if (!badApp) { try { //关键代码 didSomething |= mServices.attachApplicationLocked(app, processName); checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } // ... return true; }
attachApplication方法内部,又继续调用了attachApplicationLocked方法,attachApplicationLocked方法内部,通过IApplicationThread的bindApplication方法,IApplicationThread内部的bindApplication方法内,通过sendMessage(H.BIND_APPLICATION, data),这样ActivityThread内的内部类H,它是继承了Handler的,这样H类的handleMessage方法中的代码执行,这样handleBindApplication()方法就执行了,handleBindApplication()方法主要
做了三件事:
1.创建Instrumentation对象;
2.调用LoadedApk类的makeApplication方法创建Application对象
3.调用Instrumentation对象的callApplicationOnCreate方法
经过上面三个步骤,Application就创建了,并且它的OnCreate方法也执行了。
继续看AMS类的attachApplicationLocked方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java @GuardedBy("this") private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { // ... try { // ... if (app.isolatedEntryPoint != null) { thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } // ... } // ... // Find any services that should be running in this process... if (!badApp) { try { //关键代码 didSomething |= mServices.attachApplicationLocked(app, processName); checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } // ... return true; }
这个方法内部,还会继续执行mServices.attachApplicationLocked(app, processName);
mServices是ActiveServices类型的,所以跳转到ActivieServices类中执行
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException { boolean didSomething = false; // Collect any services that are waiting for this process to come up. if (mPendingServices.size() > 0) { ServiceRecord sr = null; try { for (int i=0; i<mPendingServices.size(); i++) { // ... //关键代码 realStartServiceLocked(sr, proc, sr.createdFromFg); // ... } } // ... } // ... return didSomething; } private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { // ... boolean created = false; try { // ... //关键代码 app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true; } // ... // 关键代码 sendServiceArgsLocked(r, execInFg, true); // ... }
这个方法中的app.thread对象就是ApplicationThread类型的对象,所以跳转到 ApplicationThread类的scheduleCreateService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false); // ... // 关键代码 sendMessage(H.CREATE_SERVICE, s); } public void handleMessage(Message msg) { // ... 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); // ... } 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 { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); } 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 app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService()); 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); } } }
scheduleCreateService方法内部最终会调用到handleCreateService方法,
handleCreateService方法内部主要做了如下事情:
1.通过类加载方式创建Service的实例对象
2.调用LoadedApk的makeApplication方法创建Application对象,由于在前面的步骤中已经创建了
Application对象,所在这个方法中,就直接返回之前创建的Application对象。
3.调动Service的attach方法,attach方法内部,主要是调用attachBaseContext,将ContextImpl对象赋值给Service父类的mBase对象。`
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/Service.java
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
//关键代码
attachBaseContext(context);
// ...
}
4.调用Servcie的onCreate方法,这样Service的OnCreate方法就执行了
至此,Servcie创建了并且调用了OnCreate方法,下面继续看看ActiveServices类的realStartServiceLocked方法中的sendServiceArgsLocked方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { // ... boolean created = false; try { // ... //关键代码 app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true; } // ... // 关键代码 sendServiceArgsLocked(r, execInFg, true); // ... } private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { // ... try { r.app.thread.scheduleServiceArgs(r, slice); } // ... }
sendServiceArgsLocked方法中的r.app.thread其实就是IApplicationThread类型的对象,所以最终会执行
ApplicationThread类中的scheduleServiceArgs方法,下面来看这个方法具体实现:
http://androidxref.com/9.0.0_r3/xref/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++) { //... // 关键代码 sendMessage(H.SERVICE_ARGS, s); } } public void handleMessage(Message msg) { 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; } private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null) { try { // ... 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; } // ... } // ... } }
handleServiceArgs方法中,执行了Servcie的onStartCommand方法,至此,Service的onStartCommand方法得到执行。
以上便是startServcie启动Servcie的过程分析。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。