浅析startService在一个新进程中启动的流程
来源:互联网 发布:董宇阳,知乎 编辑:程序博客网 时间:2024/04/30 21:31
我们一般在写代码的时候,都会通过startService来启动一个服务,但是服务到底是怎样启动的以及startService到底做了哪些工作呢?现在就来把整个过程进行整理。
我们知道Service的启动是调用了Context对象里面的startService方法,但是Context只是一个抽象类,真正的操作都是在它的实现类ContextImpl中,所以我们直接看ContextImpl里面的startService方法。
@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(); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), 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()); } } return cn; } catch (RemoteException e) { return null; } }
这里我们要打断一下,先看看ActivityManagerNative.getDefault()干了些什么,所以我们要进入ActivityManagerNative类里面,差个究竟。
static public IActivityManager getDefault() { return gDefault.get(); }
继续看源码,
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };
如果看过前面浅析PackageManager的工作流程,应该对ServiceManager.getService(“activity”)这一句代码并不陌生,因为我们的PackageManager也是使用的服务,在那篇文章中,我们获取这个服务是通过ServiceManager.getService(“package”),这样充分的说明了一点:ServiceManager就是一个服务管理者,系统的service需要通过add_service把自己的信息注册到ServiceManager中,这样在需要的时候就会获取到服务。
所以我们可以看到通过ServiceManager.getService(“activity”)可以得到远程服务的Binder对象,下面接着调用了asInterface(b),这句代码大家应该并不陌生,因为我们在编写绑定远程服务的时候就会使用,我直接贴一段小程序,激发一下大家的回忆:
public class MainActivity extends Activity { private IManager manager; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("MyService", "onServiceConnected"); //得到本地代理对象 manager = IManager.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void bindService(View view) { Log.i("MyService", "bindService"); Intent intent = new Intent("com.newintenttest.startservice.MyService"); bindService(intent, connection, Context.BIND_AUTO_CREATE); } public void unbindService(View view) { unbindService(connection); } public void caculate(View view){ if (manager == null) { Toast.makeText(this, "请绑定服务", Toast.LENGTH_SHORT).show(); } else { int result = 0; try { result = manager.add(4, 5); } catch (Exception e) { e.printStackTrace(); } Toast.makeText(this, result + "",Toast.LENGTH_SHORT).show(); } }}
这段程序来自浅析绑定远程服务bindService基本原理与AIDL分析
我们在调用了bindService(intent, connection, Context.BIND_AUTO_CREATE)后,会回调onServiceConnected方法,这个方法里面有一个IBinder类型的参数,就相当于上面的ServiceManager.getService(“activity”),都是得到远程服务的Binder对象,在上面的代码中接着调用了IManager.Stub.asInterface(service),得到本地代理对象,同理,回过头看看asInterface(b),这里肯定也是得到本地的代理对象,然后就是通过本地代理对象进行操作。
那么我们接着看看ActivityManagerNative的asInterface的操作,就可以看到这个代理对象了。
static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); }
我们写代码的时候,这些代码使用AIDL来自动生成的,其实也可以不自动生成,看看浅析绑定远程服务bindService基本原理与AIDL分析就知道了。
好了,这里其实得到的就是ActivityManagerProxy对象。我们回到上面,也就是说ActivityManagerNative.getDefault()返回了一个ActivityManagerProxy对象,接着看看这一整句代码ActivityManagerNative.getDefault().startService,调用了ActivityManagerNative里面的startService。我们进入到ActivityManagerNative类,看看里面的源码。ActivityManagerNative也在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; }
这里调用了mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0),其中mRemote就是ServiceManager.getService(“activity”)返回的Binder对象。
说到这里,如果还是不明白,强烈建议看看浅析绑定远程服务bindService基本原理与AIDL分析这篇文章,看了这篇文章之后,对于这整个过程就可以有一个宏观的理解。
接着会调用ActivityManagerNative里面的onTransact方法。
@Overridepublic 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(); int userId = data.readInt(); ComponentName cn = startService(app, service, resolvedType, userId); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; }}
从里面可以看到会调用startService(app, service, resolvedType, userId);我们发现在ActivityManagerNative里面没有startService方法,不要急,这个方法肯定存在,我们来看看ActivityManagerNative的子类ActivityManagerService类。
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } if (DEBUG_SERVICE) Slog.v(TAG, "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, userId); Binder.restoreCallingIdentity(origId); return res; } }
在这个里面调用了mServices.startServiceLocked方法,mServices是什么,在ActivityManagerService的构造函数中,我们可以看到下面一句。
private ActivityManagerService() { mServices = new ActiveServices(this);}
下面我们就要进入ActiveServices类,看看源码:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, int userId) { ...... ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, userId, true, callerFg); ........ return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); }
函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,后面调用了startServiceInnerLocked方法
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) { ProcessStats.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); 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, "Starting background (first=" + first + "): " + r, here); } else if (DEBUG_DELAYED_STATS) { Slog.v(TAG, "Starting background (first=" + first + "): " + r); } if (first) { smap.rescheduleDelayedStarts(); } } else if (callerFg) { smap.ensureNotStartingBackground(r); } return r.name; }
这里调用了bringUpServiceLocked进一步处理。
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) { ...... final String procName = r.processName; ProcessRecord app; ...... if (app == null) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", 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"; Slog.w(TAG, msg); bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } if (!mPendingServices.contains(r)) { mPendingServices.add(r); } if (r.delayedStop) { // Oh and hey we've already been asked to stop! r.delayedStop = false; if (r.startRequested) { if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r); stopServiceLocked(r); } } return null; }
这里的procName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,
接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中。
那么mAm.startProcessLocked里面的mAm是什么?
看看ActiveServices的构造函数就知道了。
public ActiveServices(ActivityManagerService service) { mAm = service; }
就是调用了ActivityManagerService里面的startProcessLocked方法
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { ...... // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, null); ...... synchronized (mPidsSelfLocked) { this.mPidsSelfLocked.put(startResult.pid, app); Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, startResult.usingWrapper ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } }
这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中.
在新进程中指定了执行ActivityThread类,下面就直接进入ActivityThread的main函数里面。
public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }}
在上面创建了一个ActivityThread对象,然后执行了它的attach方法。
private void attach(boolean system) { IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } } }
上面又执行了ActivityManagerNative.getDefault()方法,对于这个现在应该不陌生了吧,返回的就是一个ActivityManagerProxy本地代理对象.接着执行mgr.attachApplication(mAppThread)就是执行了ActivityManagerProxy里面的attachApplication方法。
其中mAppThread就是ApplicationThread对象。因为在ActivityThread里面创建了这个对象。
另外ApplicationThread继承自ApplicationThreadNative,ApplicationThreadNative继承自Binder。
final ApplicationThread mAppThread = new ApplicationThread();
接着进入ActivityManagerProxy类查看源码:
public void attachApplication(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); }
调用了ActivityManagerNative里面的onTransant方法。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case ATTACH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface( data.readStrongBinder()); if (app != null) { attachApplication(app); } reply.writeNoException(); return true; }}
它里面执行了attachApplication方法。同样,这个方法在ActivityManagerNative的子类ActivityManagerService里面。
@Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
接着跟踪attachApplicationLocked方法
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ...... // Find any services that should be running in this process... if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } } ...... return true; }
它执行了mServices.attachApplicationLocked函数,mServices就是ActiveServices对象。
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception { 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++) { sr = mPendingServices.get(i); if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid || !processName.equals(sr.processName))) { continue; } mPendingServices.remove(i); i--; proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats); realStartServiceLocked(sr, proc, sr.createdFromFg); didSomething = true; } } catch (Exception e) { Slog.w(TAG, "Exception in new application when starting service " + sr.shortName, e); throw e; } } // Also, if there are any services that are waiting to restart and // would run in this process, now is a good time to start them. It would // be weird to bring up the process but arbitrarily not let the services // run at this point just because their restart time hasn't come up. if (mRestartingServices.size() > 0) { ServiceRecord sr = null; for (int i=0; i<mRestartingServices.size(); i++) { sr = mRestartingServices.get(i); if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid || !processName.equals(sr.processName))) { continue; } mAm.mHandler.removeCallbacks(sr.restarter); mAm.mHandler.post(sr.restarter); } } return didSomething; }
这里执行了realStartServiceLocked方法,
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ...... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); ...... }
上面的app.thread是IApplicatonThread类型,最终将执行ApplicationThreadProxy里的scheduleCreateService方法。
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); info.writeToParcel(data, 0); compatInfo.writeToParcel(data, 0); data.writeInt(processState); mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); }
这个现在应该很熟悉了,接着执行ApplicationThreadNative里面的onTransact方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { 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); int processState = data.readInt(); scheduleCreateService(token, info, compatInfo, processState); return true; } }
接着就执行scheduleCreateService方法。因为ApplicationThreadNative里面没有实现scheduleCreateService这个方法,所以会执行它的子类ApplicationThread里的scheduleCreateService方法。ApplicationThread这个类在ActivityThread.java文件中。
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); }
接着会执行sendMessage方法。
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 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; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); }
从定义final H mH = new H()可以看到mH是一个H对象,而H是一个继承自Handler的类。
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"); handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } }
下面执行的就是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 { //这里创建了我们自定义的服务 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 = 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()); //执行了onCreate方法,也就是说我们的onCreate方法是在这里调用的 service.onCreate(); mServices.put(data.token, service); try { 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) cl.loadClass(data.info.name).newInstance()就创建了一个服务,data.info.name就是自定义的服务.接着就执行了service.onCreate()方法,对于这个方法应该很熟悉了,原来我们的onCreate方法是在这个地方调用的。
参考文章:
Android系统在新进程中启动自定义服务过程(startService)的原理分析
- 浅析startService在一个新进程中启动的流程
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- startService启动应用进程流程
- Android源码解析之新进程中启动自定义服务过程(startService)的原理分析
- Android系统在新进程中启动自定义服务过程(startService)的原理分析、Android应用程序绑定服务(bindService)的过程源代码分析
- Android在新进程中启动 Service 的流程原理分析
- Android app启动一个新进程流程
- Service启动流程-startService
- Python 3.4 学习总结 (2)
- Google高级搜索技巧
- Right me speak (对我自己说
- 内存对齐规则
- 针对Bug的管理措施
- 浅析startService在一个新进程中启动的流程
- CSU - 1542 Flipping Parentheses (线段树)
- ZOJ 3888 Twelves Monkeys (优先队列+预处理)
- Xcode 6 打包ipa文件
- hdu 1564 博弈
- nginx - 性能优化,突破十万并发
- DNS原理及其解析过程【精彩剖析】
- Javascript 严格模式详解
- java多线程