Android M 6.0,关于ActivityThread和ApplicationThread的解析.

    xiaoxiao2021-12-14  22

          文章仅仅用于个人的学习记录,基本上内容都是网上各中资料,此处摘录过来以自己的理解学习方式记录一下。         ActivityThread和ApplicationThread的理解在你阅读源代码尤其和进程启动,service、activity启动等相关的代码时,就能发现其重要性了。 1、ActivityThread.         在Android中它就代表了Android的主线程,注意是代表而不是说它就是一个Thread类,它是创建完新进程之后(肯定是在     一个线程中啊),main函数被加载,然后执行一个loop的循环使当前线程进入消息循环,并且作为主线程。接下来还会初始化     很多 必要 的属性.   它的很多成员变量和内部类十分的重要,深入理解这些成员变量有助于我们进一步的认识Android系统的各个组件的交互。        1.1、它的main函数如下. public static void main(String[] args) { ......   Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread();//实例化这个类 thread.attach(false);//这个attach也很关键后面分析.   if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler();//很重要mainHandler用于处理UI线程的各种信息 } ......   Looper.loop(); //可以看出来主线程也是在无限的循环的,异常退出循环的时候会报错.   throw new RuntimeException("Main thread loop unexpectedly exited"); }             注意此处虽然new 出了ActivityThread的实例但是它的局部的啊,那我们怎么得到这个实例那? private static ActivityThread sCurrentActivityThread; public static ActivityThread currentActivityThread() { return sCurrentActivityThread; } private void attach(boolean system) { sCurrentActivityThread = this; ......//其它的我们后面专门分析. }             通过currentActivityThread()的方法.         1.2、final ApplicationThread mAppThread = new ApplicationThread();这个成员变量我们后面专门分析.                  它就是作为服务端,接收ActivityManagerService的指令并执行.是ActivityThread与AMS连接的桥梁.         1.3、final H mH = new H()                   这个H是继承自Handler的,它是个私有的内部类,其实就是主线程的Handler,通过这个Handler就可以往主线程               的消息队列发消息如:启动Activity、service,接收广播等等,很多重要的工作.                   这个成员变量mH默认权限修饰符可以通过ActivityThread的如下方法来获得. private class H extends Handler {......} final Handler getHandler() { return mH; }                  这个消息队列可以说是一个中转站,用来更好的分类管理各种类别的业务的处理,如AMS创建service,通过              mAppThread 这个 binder对象的 成员变量当中的方法,进而往消息队列中发送相应的消息,然后在不同的case中作出             相应的处理.如:startservice()的流程最后.调用到 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); } case CREATE_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; private void handleCreateService(CreateServiceData data) { ...... 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) { ...... }   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(); mServices.put(data.token, service); try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { ...... } }            这样最终完成service的启动,调用到service的onCreate的方法,很多这样的调用模式,需要熟悉。            这样我们就会发现ActivityThread中好多类似的重要的方法用于最终的事件处理.如下: handleActivityConfigurationChanged() handleBindApplication() handleBindService() handleCancelVisibleBehind() handleConfigurationChanged() handleCreateService() handleDestroyActivity() handleDispatchPackageBroadcast() handleLaunchActivity() handleLowMemory() handleMessage() handleNewIntent() handlePauseActivity() handleReceiver() handleRelaunchActivity() handleResumeActivity() handleSendResult() handleServiceArgs() handleStopActivity() handleStopService() handleUnbindService()         光看名字都能感觉到这些函数的重要性,而这些函数有的又会调用到如下的系列函数完成最终的事件处理. performDestroyActivity() performDestroyActivity() performLaunchActivity() performNewIntents() performPauseActivity() performPauseActivity() performRestartActivity() performResumeActivity() performStopActivity() performStopActivityInner() performUserLeavingActivity()          1.4、成员变量 mActivities.               它包含了当前进程的所有的activity,(一个进程对应一个ActivityThread)注意不是简单的把activity做了数据集            合,而是封装成了 ActivityClientRecord.            final ArrayMap<IBinder,ActivityClientRecord> mActivities  = new ArrayMap<IBinder,ActivityClientRecord>()               那么就需要看一下 ActivityClientRecord了. static final class ActivityClientRecord { IBinder token; int ident; Intent intent; String referrer; IVoiceInteractor voiceInteractor; Bundle state; PersistableBundle persistentState; Activity activity; Window window; Activity parent; String embeddedID; Activity.NonConfigurationInstances lastNonConfigurationInstances; boolean paused; boolean stopped; boolean hideForNow; Configuration newConfig; Configuration createdConfig; ActivityClientRecord nextIdle;   ProfilerInfo profilerInfo;   ActivityInfo activityInfo; CompatibilityInfo compatInfo; LoadedApk packageInfo;   List<ResultInfo> pendingResults; List<ReferrerIntent> pendingIntents;   boolean startsNotResumed; boolean isForward; int pendingConfigChanges; boolean onlyLocalRequest;   View mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager;   ActivityClientRecord() { parent = null; embeddedID = null; paused = false; stopped = false; hideForNow = false; nextIdle = null; } ...... public boolean isPersistable() { return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS; } ...... }          在ActivityThread当中最终通过performLaunchActivity()来完成Activity的启动.先只贴出要分析的代码. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ......//完成Activity的启动. mActivities.put(r.token, r); }          可以看到最终完成Activity在本进程中的启动的时候,会以ActivityClientRecord的成员变量token为key,以 ActivityCli       e nt Record为value.存入到mActivitys当中.这个token是一个IBinder的变量.(??最后补上)那么问题的关键就是 ActivityCli e       n t Record是怎么实例化然后传入过来的?我们在往上一层跟. public final Activity startActivityNow(Activity parent, String id, Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state, Activity.NonConfigurationInstances lastNonConfigurationInstances) { ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = 0; r.intent = intent; r.state = state; r.parent = parent; r.embeddedID = id; r.activityInfo = activityInfo; r.lastNonConfigurationInstances = lastNonConfigurationInstances; ...... return performLaunchActivity(r, null); }         可以看到很多关键信息都是由调用给这个方法的类传入的,其实就是AMS.我们在分析Activity启动的时候会详细分析.相对      非常重要的有token、intent、activityInfo等.尤其这个ActivityInfo包含了太多的Activity的信息.                1.5、成员变量 mServices               它和mActivities类似的处理方式,里面也是包含了当前进程中所有的services,不过就是直接存放的当前Service的信息,没有封装 = new ArrayMap<IBinder, Service>(); private void handleCreateService(CreateServiceData data) { try { ...... mServices.put(data.token, service); ...... } catch (Exception e) { ...... } }              也是最终完成startService的流程后,以key = CreateServiceData.token,Value = 启动的Service.存入到 mServices               当中。那么问题又来了我们就需要看一下 CreateServiceData怎么来的了.                首先 handleCreateService是由mH中的case走过来的.         case CREATE_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;             找到本类中发送消息的地方. 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); }             也同样可以看到 CreateServiceData就是把一些关键的信息封装到了一起如:token、info等,这些在分析启动service         的流程的时候一定要仔细.           1.6、其它                还有很多的成员变量如:                    Configuration mConfiguration;                    final ArrayList<Application> mAllApplications = new ArrayList<Application>();                    final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>();                    final ArrayMap<ProviderKey,ProviderClientRecord> mProviderMap = new ArrayMap<ProviderKey,ProviderClientRecord>();                    final ArrayMap<IBinder,ProviderClientRecord> mLocalProviders = new ArrayMap<IBinder ProviderClientRecord>();                还有很多的内部类如:                           static final class BindServiceData :用来封装使用bindeservice启动的时候的service的信息.                          static final class ReceiverData    : 用来封装和广播处理相关的一些信息.                          final class ProviderClientRecord   : 用来封装和Provider交互的一些信息                            static final class AppBindData     : 用来封装和Application交互时的一些信息.               这些都不一一分析了.遇到的时候或者感兴趣的时候再去研究一下.         1.7、最后我们再分析一下attach的方法.                这个方法在新进程启动完毕后会在main方法中调用,这是一种调用方法,其实它还会在systemMain()当中调用并且             传 入的参数是true.它是由SystemServer.java调用的(没研究过这块的启动应该是系统的某个初始进程,没走Zygote)    private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ...... final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread);//很关键. } catch (RemoteException ex) { // Ignore } // Watch for getting close to heap limit. ...... } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } }   ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { ...... sendMessage ( H . CONFIGURATION_CHANGED , newConfig ); ..... } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); }            此处我们重点关注非系统的的逻辑.是通过mgr.attachApplication(mAppThread)调用AMS的对应方法,(发现解锁Binder)        以后真的是读代码各种顺.注意:mAppThread对象的传入. @Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }           获得了正在Binder通信的客户端的uid然后和ApplicationThread对象作为参数传入到AMS的attachApplicationLocked中 private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {   // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid);//在整个启动进程的流程中在前面已经push进入 } } else { app = null; } if (app == null) { ...... return false;//为null的时候直接返回. } //正常第一次开启时此时还是null if (app.thread != null) { handleAppDiedLocked(app, true, true); } ...... final String processName = app.processName; ...... //下面这个方法很关键,来时例化ProcessRecord的thread变量.它是一个IApplicationThread对象.   app.makeActive(thread, mProcessStats);//在这里实现的附着! app.curAdj = app.setAdj = -100; app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; app.forcingToForeground = null; updateProcessForegroundLocked(app, false, false); app.hasShownUi = false; app.debugging = false; app.cached = false; app.killedByAm = false;   mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);   boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; ...... try { ...... thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { ...... return false; }   // Remove this record from the list of starting applications. mPersistentStartingProcesses.remove(app); if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, "Attach application locked removing on hold: " + app); mProcessesOnHold.remove(app);   boolean badApp = false; boolean didSomething = false;   // See if the top visible activity is waiting to run in this process... if (normalMode) { ..... }   // Find any services that should be running in this process... if (!badApp) { ...... }   // Check if a next-broadcast receiver is in this process... if (!badApp && isPendingBroadcastProcessLocked(pid)) { ...... }   // Check whether the next backup agent is in this process... if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { ...... }   if (badApp) { ...... }   if (!didSomething) { ...... }   return true; }          在此处我们集中在为ProcessRecord的成员变量IApplicationThread thread赋值的步骤,也就是调用ProcessRecord中的       makeActive(thread,mProcessStats); public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {//zy 它就是赋值thread. if (thread == null) { ...... } thread = _thread; } 2、ApplicationThread.       它是ActivityThread的私有内部类,也是一个Binder对象。在此处它是作为IApplicationThread对象的server端等待client端    的请求然后进行处理,最大的client就是AMS. private class ApplicationThread extends ApplicationThreadNative { public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { ...... } public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) { ...... } public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { ...... } ......   }        可以看出来它是继承自ApplicationThreadNative的,并且它内部有非常多的scheduleXXX的方法.以后看到thread调用这个方法     就可以往这边找。我们先说一下这些方法,这些方法由外部的ActivityThread的binder远程代理对象调用最终走到这里.这些     schedulexxx的方法会进一步的通过往外发送消息给mH这个消息队列.来做处理.比如: 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); }        比较重要的 schedulexxx方法有: schedulePauseActivity() scheduleStopActivity() scheduleResumeActivity() scheduleSendResult() scheduleLaunchActivity() scheduleNewIntent() scheduleDestroyActivity() scheduleReceiver() scheduleCreateService() scheduleBindService() scheduleUnbindService() scheduleServiceArgs() scheduleStopService() bindApplication() scheduleConfigurationChanged() scheduleRegisteredReceiver() scheduleInstallProvider() 还有很多dump信息的处理         这些方法放在此处眼熟,暂时没精力一个个分析,从名字也能看出大概的功能.         接下来我们再看看 ApplicationThreadNative,看这个函数的名字感觉就应该是被实现为了一个Binder对象。 /** {@hide} */ public abstract class ApplicationThreadNative extends Binder implements IApplicationThread { //根据传入的不同参数决定返回不同的值. static public IApplicationThread asInterface(IBinder obj) { if (obj == null) { return null; } IApplicationThread in = (IApplicationThread)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ApplicationThreadProxy(obj); }   public ApplicationThreadNative() { attachInterface(this, descriptor); } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { ...... } } public IBinder asBinder() { return this; }   }         果不其然啊,并且还是先了业务接口IApplicationThread,非常标准的Binder模板.IApplicationThread extends IInterface      它里面就是定义了非常多的通信的业务接口,也都是schedulexxx理解上对应到 ApplicationThread那些方法.         首先是提供了一个静态的方法asInterface()用来获取IApplicationThread的Binder对象或者Binder代理对象,其 它进程跨进      程调用时候当传入的是BinderProxy那么就会返回一个ApplicationThreadProxy对象并把BinderProxy传入它的构 造.而一般在      本进程中调用的时候,就直接返回当前 IApplicationThread对象.然后就是onTransact()函数了,里面通过不同的code对应到不      同的case,进而调用不同的schedulexxx的方法,最终调入到 ApplicationThread中的schedulexxx.          ApplicationThread这样就完成了作为服务端的构架,接下来就就是代理端的分析了.前面我们知道跨进程调用asInterface的      时候返回的是ApplicationThreadProxy对象,该类位于 ApplicationThreadNative.java文件当中,但是不是内部类,同文件而已.            class ApplicationThreadProxy implements IApplicationThread { private final IBinder mRemote; public ApplicationThreadProxy(IBinder remote) { mRemote = remote; } public final IBinder asBinder() { return mRemote; } public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(finished ? 1 : 0); data.writeInt(userLeaving ? 1 :0); data.writeInt(configChanges); data.writeInt(dontReport ? 1 : 0); mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException { ...... } ......//一些列的schedulexxx     }         也是代理端的标准实现,实现了IApplicationThread 接口,然后重写出接口中定义的业务方法,在每个方法中最终调用到了      服务端的对应的schedulexxx方法中.通过mRemote变量和驱动去交互进而调用到server端,  mRemote是一个BinderProxy对象.         关于 IApplicationThread 的Binder相关实现,有个需要注意的它没有趣service manager中注册,走的是一个匿名的binder的      方法,其实对于驱动来说都一样.暂时发现的是别的地方如AMS用的时候通过ActivityThread的接口获得到 ApplicationThread的      对象,然后传入到asInterface(),获取对应的 IApplicationThread 对象进行跨进程调用.     3、Instrumentation.       在android.app包下有Instrumentation这个类,这个类没有继承和实现其它的任何类,也没被其它的类继承.会在应用的任何    代 码执行前被实列化,用来监控系统组件与应用的交互过程,其实就是很多操作封装一下,由它来完成实现. Instrumentation另    一个重要作用是提供Android组件单元测试           每一个应用进程中只有唯一的Instrumentation, 在ActivityThread中 成员变量Instrumentation mInstrumentation,通过方法        public  Instrumentation getInstrumentation()来获得.
    转载请注明原文地址: https://ju.6miu.com/read-968192.html

    最新回复(0)