通过分析点击android桌面app图标启动应用程序的过程这篇文章,我们了解启动activity的过程,再来分析启动android的另一个组件service的过程就比较容易了.因为流程差不多.
现在假设应用程序有一个activity和一个service,然后在activity中通过startService()启动service,清单文件中service的process属性没有设置.也就是activity和service在一个进程中.
startService()这个方法是Activty的父类ContextWrapper中的.
frameworks/base/core/java/android/content/ContextWrapper.java
public ComponentName startService(Intent service) { return mBase.startService(service); }这里mBase变量是ContextImpl类型,是在创建activity的时候,new 一个 ContextImpl对象,赋值给activity的.
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ..... if (activity != null) { Context appContext = createBaseContextForActivity(r, activity);//创建contextImpl CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); ..... activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config);//传进去 ..... return activity; }
第一步:frameworks/base/core/java/android/app/ContextImpl.java
public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceAsUser(service, mUser); } @Override public ComponentName startServiceAsUser(Intent service, UserHandle user) { try { service.setAllowFds(false); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); .... return cn; } catch (RemoteException e) { return null; } }
mMainThread.getApplicationThread()是ApplicationThread类型的mAppThread对象,ApplicationThread其实是Binder类型.是用来和ActivityManagerService进程间通信的,它是在ActivityThread类中创建的.
service.resolveTypeIfNeeded(getContentResolver())获取这个intent的MIME类型,这里假设没有设置MIME类型 即AndroidManifest.xml没有设置Service的MIME类型,所以这里返回null.
第二步:
frameworks/base/core/java/android/app/ActivityManagerNative.java
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); service.writeToParcel(data, 0); data.writeString(resolvedType); data.writeInt(userId); mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); reply.readException(); ComponentName res = ComponentName.readFromParcel(reply); data.recycle(); reply.recycle(); return res; }
case START_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); int userId = data.readInt(); ComponentName cn = startService(app, service, resolvedType, userId); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; }
第三步:startService().
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java.
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) { ..... synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); checkValidCaller(callingUid, userId); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } }
frameworks/base/services/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, int userId) { .... if (caller != null) { final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null) { ..... } } ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, userId, true); if (res == null) { ... } if (res.record == null) { ... } ServiceRecord r = res.record; ...... String error = bringUpServiceLocked(r, service.getFlags(), false); .... return r.name; }函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中.
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting) { .... if (r.app != null && r.app.thread != null) { ... } ..... final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; ProcessRecord app; if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);//这里获取不为空,因为该service所在的进程已经启动起来了 .... if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName); realStartServiceLocked(r, app); return null; } catch (RemoteException e) { ... } ..... } } else { ... } .... return null; }这里service所在的进程已经启动起来了,所以接下来直接在这个进程中启动service.
第六步:realStartServiceLocked().ActiveServices.java中
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app) throws RemoteException { ... try { .... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));//去创建service r.postNotification(); created = true; } finally { ... } ..... sendServiceArgsLocked(r, true); }首先看scheduleCreateService方法,
frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中,这里又是Binder进程间通信了.
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); info.writeToParcel(data, 0); compatInfo.writeToParcel(data, 0); mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); }
case SCHEDULE_CREATE_SERVICE_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); IBinder token = data.readStrongBinder(); ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data); CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); scheduleCreateService(token, info, compatInfo); return true; }
第八步:scheduleCreateService().
在frameworks/base/core/java/android/app/ActivityThread.java中
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().
在frameworks/base/core/java/android/app/ActivityThread.java中
private void queueOrSendMessage(int what, Object obj) { queueOrSendMessage(what, obj, 0, 0); } private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { synchronized (this) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; mH.sendMessage(msg); } }
第十步:handleCreateService().
在frameworks/base/core/java/android/app/ActivityThread.java中
case CREATE_SERVICE: ... handleCreateService((CreateServiceData)msg.obj); ... break;
private void handleCreateService(CreateServiceData data) { ... Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance();//创建一个service实例 } catch (Exception 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的onCreat()方法 mServices.put(data.token, service); try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, 0, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { ... } }
接下来回到第六步,另外一个方法sendServiceArgsLocked();
第十一步:sendServiceArgsLocked().
frameworks/base/services/java/com/android/server/am/ActiveServices.java
private final void sendServiceArgsLocked(ServiceRecord r, boolean oomAdjusted) { ..... r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); .... }
这里我就省略中间的几步了,和第七步类似.
第十二步:sendServiceArgsLocked().
在frameworks/base/core/java/android/app/ActivityThread.java中
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; queueOrSendMessage(H.SERVICE_ARGS, s); }
第十三步:handleServiceArgs().
在frameworks/base/core/java/android/app/ActivityThread.java中
private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null) { try { ... if (!data.taskRemoved) { res = s.onStartCommand(data.args, data.flags, data.startId); } else { ..... }s.onStartCommand()这个方法会先回调service的onStart()方法,这样onStart()和onStartCommand()就被相继调用了,这两个回调大家应该也熟悉吧.
这就是启动service的过程的了.