Service的启动流程源码跟踪

it2024-12-22  3

前言:

当我们在一个Activity里面startService的时候,具体的执行逻辑是怎么样的?需要我们一步步根据源码阅读。

在阅读源码的时候,要关注思路,不要陷在具体的实现细节中,一步步整理代码的思路。

注:源码使用Api 25的

1.起点:Activity-> startService

在Activity中没有找到startService的方法, 查看Activity的继承关系: Context->ContextWrapper->ContextThemeWrapper->Activity 回溯到ContextWrapper中,找到了startService()的方法:

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

从ContextWrapper的命名和方法的实现上,我们可以猜到其实ContextWrapper只是一个包装 真正实现startService逻辑的是调用mBase.startService(service); 其中 Context mBase;是一个成员变量 由于Context是一个抽象类,startService是它的抽象方法,所以一定存在一个Context的子类实现了Context的抽象方法。 其实就是ContextImpl类,所以Context的抽象方法的具体实现由ContextImpl负责,其他Context的子类只需要在自己的方法里面调用 ContextImpl的即可。

2.ContextImpl ->startService(Intent service)

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

调用到startServiceCommon(service, mUser)

private ComponentName startServiceCommon(Intent service, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), getOpPackageName(), user.getIdentifier()); //省略部分代码 } return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }

可以看到是调用ActivityManagerNative的 ActivityManagerNative.getDefault().startService方法

3.ActivityManagerNative-> ActivityManagerNative.getDefault().startService

观察public abstract class ActivityManagerNative extends Binder implements IActivityManager的定义 可以猜测这是一个可以Binder进程IPC操作的类。 PS:如果你对Binder还很陌生推荐你先了解Binder,不需要深入到底层实现,不过Java层的基本用法需要了解 下面的博客都可以参考: weishu的博客 Gityuan的博客 引用一个对Binder很精彩的描述: Binder使得一个进程A有一个真身,它实现了具体的逻辑,然后其他进程获得的是Binder的影子(或者说是引用?句柄?) 然后其他进程通过Binder的影子调用就仿佛调用了A的真身的操作。 其实很多资料都告诉我们启动四大组件是IPC的操作,app进程必须通过IPC与另外的进程通信,完成四大组件的启动。 结合上面的描述,我们知道,那么app进程的是影子。我们找到它: 在ActivityManagerNative它有一个子类:

class ActivityManagerProxy implements IActivityManager{ //省略代码 public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, 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.writeString(callingPackage); data.writeInt(userId); mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);//挂起,通过Binder驱动IPC reply.readException(); ComponentName res = ComponentName.readFromParcel(reply); data.recycle(); reply.recycle(); return res; } //省略代码 }

这就是影子,我们在App进程调用的startService最终会到达这里,然后经过Binder驱动的一系列操作到达另外一个进程的真身

所以:ActivityManagerNative.getDefault()这里获取的应该就是ActivityManagerProxy 的实例,我们看一下它的实现:

static public IActivityManager getDefault() { return gDefault.get(); } …. ** gDefault **这是一个单例对象 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity");//注意这里,通过**ServiceManager**获取的字符串"activity"的IBinder if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } }; }

我们可以看到最终获取的是:IActivityManager am = asInterface(b);

asInterface的代码:

/** * Cast a Binder object into an activity manager interface, generating * a proxy if needed. */ static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } //如果是不是IPC调用执行下面的代码: IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //如果是IPC调用执行下面的代码: return new ActivityManagerProxy(obj); }

可以看到我们通过:return new ActivityManagerProxy(obj); 获取到了影子的实例。 一句话总结:ActivityManagerNative.getDefault().startService() 最终调用的是ActivityManagerProxy 的startService()方法 这里将有一个IPC的逻辑: mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); 经过Binder驱动的各种操作 最终是运行到ActivityManagerNative的 onTransact方法里面的。

ActivityManagerNative->onTransact()

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { //省略代码 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(); String callingPackage = data.readString(); int userId = data.readInt(); ComponentName cn = startService(app, service, resolvedType, callingPackage, userId); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; } //省略代码 } 最终调用的是: ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);(注意这里已经不是运行在App的进程的,而是在system_Server进程中,system_Server是由Zygote进程孵化出来的。) 在ActivityManagerNative中找不到 startService(app, service, resolvedType, callingPackage, userId);这个方法,由于ActivityManagerNative是一个抽象类,自然想到方法的实现在子类中,其实就是ActivityManagerService

4.ActivityManagerService->startService()

@Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // 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"); } if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType); synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } }

调用的是mServices.startServiceLocked()方法 mService是: final ActiveServices mServices;

5.ActiveServices ->startServiceLocked

最终调用的是

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); } if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; smap.mStartingBackground.add(r); r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT; if (DEBUG_DELAYED_SERVICE) { RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here); } else if (DEBUG_DELAYED_STARTS) { Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r); } if (first) { smap.rescheduleDelayedStarts(); } } else if (callerFg) { smap.ensureNotStartingBackground(r); } return r.name; }

startServiceInnerLocked()调用的是 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); bringUpServiceLocked(r, service.getFlags(), callerFg, false, false)方法: private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { //省略代码 if (!isolated) { //注意这里获取的需要启动Service的进程的信息 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. } } else { // If this service runs in an isolated process, then each time // we call startProcessLocked() we will get a new isolated // process, starting another process if we are currently waiting // for a previous process to come up. To deal with this, we store // in the service any current isolated process it is running in or // waiting to have come up. app = r.isolatedProc; } //省略代码

}

调用到了realStartServiceLocked()

private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException { //省略代码 这里就回到的app的进程 app.thread.scheduleCreateService(r,r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState); //省略代码 }

最终调用ActivityThread里面的ApplicationThread->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); }

6.由ActivityThread的内部的Handler处理 sendMessage(H.CREATE_SERVICE, s);发送的消息

private class H extends Handler { public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { //略 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; //略 } }

最终是通过反射创建一个新的Service,然后调用它的onCreate()方法

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 = (Service) cl.loadClass(data.info.name).newInstance();//反射创建一个新的Service } 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); Application app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); service.onCreate();//调用Service的onCreate()方法 mServices.put(data.token, service); try { ActivityManagerNative.getDefault().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); } } }

总结:

我们可以看到其实启动一个Service的过程也是挺复杂的,由于能力所限,仅跟踪了Java Framework这一层的代码,深入到底层的就不分析了。可以参考Gityuan大神的博客。

转载于:https://www.cnblogs.com/bylijian/p/7372180.html

最新回复(0)