本文主要是介绍startService启动流程---Service在App进程但未启动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在Service启动流程(startService)的最后,分析了在调用startService时可能存在的三种情况,本文分析第二种情况—Service与App在同一个进程,但未启动。
Service启动流程(startService)最后已经说明,在这种情况下,系统会执行realStartServiceLocked
函数。
private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app) throws RemoteException {......r.app = app;r.restartTime = r.lastActivity = SystemClock.uptimeMillis();app.services.add(r);bumpServiceExecutingLocked(r, "create");updateLruProcessLocked(app, true, true);boolean created = false;try {......//跨进程去执行Service实例的创建app.thread.scheduleCreateService(r, r.serviceInfo,compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));r.postNotification();created = true;} finally {if (!created) {app.services.remove(r);scheduleServiceRestartLocked(r, false);}}......//Service创建完成后,执行onStartCommand函数sendServiceArgsLocked(r, true);
}
函数的逻辑还是比较清晰的,完成的工作主要有两个:
- 创建Service实例
- 执行onStartCommand方法
接下来就来看下这两个任务时如何完成的。
创建Service实例是一个Binder跨进程调用,Binder细节就不分析,直接进入ActivityThread查看scheduleCreateService
的实现
public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo) {CreateServiceData s = new CreateServiceData();s.token = token;s.info = info;s.compatInfo = compatInfo;queueOrSendMessage(H.CREATE_SERVICE, s);}
好吧,queueOrSendMessage
这个函数我们在ActivityThread中已经看到过很多次调用很多次了,我们直接进入到真正执行创建Service实例的函数queueOrSendMessage
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.......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 = new ContextImpl();context.init(packageInfo, null, this);Application app = packageInfo.makeApplication(false, mInstrumentation);context.setOuterContext(service);service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());//执行Service onCreate方法service.onCreate();mServices.put(data.token, service);try {//通知ActivityManagerService实例创建完成ActivityManagerNative.getDefault().serviceDoneExecuting(data.token, 0, 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);}}
}
函数的代码不短也不长,还是比较好理解的。首先获取Service的信息,然后调用反射创建Service实例(想想Activity实例的创建,是不是也是反射?),创建完实例后就会去执行attach方法,执行完attach方法后就会去执行onCreate方法(想想Activity,是不是也是先执行attach在执行onCreate?),执行完onCreate方法后,通知ActivityManagerService。
执行完Service实例的创建,接下来执行onStartCommand
的流程就是 startService启动流程—Service已经启动中描述的流程,我就不再分析了。
这篇关于startService启动流程---Service在App进程但未启动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!