前言
从第一天接触Android开发开始,大家都知道Activity是Android中最最最重要的一个组件。既然很重要,很多在Android开发岗位工作几年了,都对Activity讲不出个所以然出来。比如:
1.Activity的创建
2.Activity生命周期函数的调用
既然这么重要,这么多问题困扰小伙伴们,希望通过本章的学习,帮助小伙伴们对Activity有个全新的认识。
众所周知,java程序想要开启需要依赖于main方法,也就是程序入口(主线程)进入。熟悉的小伙伴可能都知道在Android当中存在一个叫做ActivityThread的类,这个类代表的是Android当中的主线程,而在这个类当中会有一个比较熟悉的main方法,Android在打开app时首先调用的是ActivityThread的main方法,这也就是一个app进程的启动点。
##ActivityThreadpublic static void main(String[] args) { ... Looper.prepareMainLooper(); long startSeq = 0; if (args != null) { for (int i = args.length - 1; i >= 0; --i) { if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { startSeq = Long.parseLong( args[i].substring(PROC_START_SEQ_IDENT.length())); } } } ActivityThread thread = new ActivityThread(); //1 thread.attach(false, startSeq); //2 ... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");}
在main方法的注释1处,创建了ActivityThread,接着在注释2处,调用了attach方法,意为连接,具体连接什么,我们接着往下分析。
##ActivityThreadprivate void attach(boolean system, long startSeq) { ... if (!system) { ... final IActivityManager mgr = ActivityManager.getService(); //1 try { mgr.attachApplication(mAppThread, startSeq); //2 } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ... } else { ... } ...}
attach方法,在注释1处,通过AIDL,得到AMS的本地代理对象IActivityManager ,作用应用进程请求系统进程的接口,实现跟AMS服务跨进程间通信。这里设计到AIDL的用法,和AMS相关的基础知识,这部分内容不在本章节探讨。接着看注释2,使用IActivityManager 对象调用了attachApplication方法,主要是为了连接Application。Application这个类小伙伴们肯定是不陌生的,一般会在这个类中去初始化一些需要在Activity启动之前初始化的资源,或是配置一些整个应用需要用到的东西,让真个App(任何类中)都能访问到。那么这里跟AMS进行连接,主要让当前App跟Android系统绑定起来,方便系统管理当前App。
##ActivityManagerServicepublic final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { //获取pid int callingPid = Binder.getCallingPid(); //1 //获取uid final int callingUid = Binder.getCallingUid(); //2 final long origId = Binder.clearCallingIdentity(); //连接Application attachApplicationLocked(thread, callingPid, callingUid, startSeq); //3 Binder.restoreCallingIdentity(origId); }}
attachApplication是AMS中的一个方法,注释1和2分别获取到pid和uid(由系统创建,并分配,并且是处以没有进程使用)。这里小伙伴们可以猜想一下,获取到pid和uid肯定是把它分配到当前进程。在注释3,可以看到pid和uid传入到了attachApplicationLocked这个方法中。
##ActivityManagerServiceprivate final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { ProcessRecord app; //1 long startTime = SystemClock.uptimeMillis(); if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); //2 } } ... if (app.instr != null) { //当前进程是否正在活动 thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); //3 } else { //Application 绑定到当前线程 thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); //4 } ... //检测最可见的Activity是否在运行进程中等待,如果再则创建Activity if (mStackSupervisor.attachApplicationLocked(app)) { //5 didSomething = true; } ...}
attachApplicationLocked方法中,注释1处的ProcessRecord是个进程记录类,小伙伴们可以把这个类理解成为一个javabean,用来保存当前进程先关的一些信息(如pid、uip、ApplicationInfo等),在注释2中,根据pid获取到了这个类。注释3和注释4都是为了绑定Application,调用的是IApplicationThread 中的bindApplication方法,而IApplicationThread 它是一个AIDL接口,作用是系统进程请求应用进程的接口。而它的实现类是在ActivityThread中的一个内部类ApplicationTread继承了IApplicationThread.Stub。注释5是开始创建Activity。这里我们分开来探讨绑定Application和创建Activity。
绑定Application
##ActivityThread.ApplicationThreadpublic final void bindApplication(String processName...boolean autofillCompatibilityEnabled) { ... setCoreSettings(coreSettings); AppBindData data = new AppBindData(); data.processName = processName; //当前进程名字 data.appInfo = appInfo; //app信息 data.providers = providers; //providers ... //最后使用Handler发送消息,并携带AppBindData数据 sendMessage(H.BIND_APPLICATION, data);}
在ActivityThread.ApplicationTread类中,bindApplication方法携带了一系列参数,把这些数据封装成了一个AppBindData 对象,最后使用Handler发送消息,并携带AppBindData数据。H是ActivityThread中的内部类,是Handler的子类。
##ActivityThread.Hpublic void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case BIND_APPLICATION: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); AppBindData data = (AppBindData) msg.obj; handleBindApplication(data); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... } ...}
handleMessage方法是H中的方法,主要是用来处理消息。
##ActivityThread private void handleBindApplication(AppBindData data) { ... final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); //1 ... Application app; ... //创建Application app = data.info.makeApplication(data.restrictedBackupMode, null); //2 ... //调用Application中的onCreate方法 mInstrumentation.callApplicationOnCreate(app); //3 ...}##Instrumentationpublic void callApplicationOnCreate(Application app) { app.onCreate();}
handleBindApplication方法中,注释1,获取Application的上下文,也就是getApplicationContext()获取到的ContextImpl ,ContextImpl 是Context的子类。注释2,通过类加载器,和反射创建出Application。注释3,接着可以看到Application的onCreate方法的调用。
小结,链接Application,可以理解为三个步骤,第一个步骤获取pid和uid,第二步通过IApplicationThread请求当前应用进程,第三步创建Application。
##ActivityStackSupervisorboolean attachApplicationLocked(ProcessRecord app) throws RemoteException { ... if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } ...}
经过一系列的检测或判断后,会realStartActivityLocked方法,真正的开始Activity的解锁(创建)。
##ActivityStackSupervisorfinal boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... // 创建启动Activity final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); //添加LaunchActivityItem的回调 // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // 通过生命周期管理对象ClientLifecycleManager,来管理Activity的生命周期状态 mService.getLifecycleManager().scheduleTransaction(clientTransaction); ... return true;}
此处,添加LaunchActivityItem。再后续的真正开始创建Activity时会用到。
##ClientLifecycleManagervoid scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); //ClientTransaction是个javabean 实现了Parcelable 序列化。 //schedule()方法内部,会回调到ActivityThread.ApplicationThread的scheduleTransaction()方法 transaction.schedule(); if (!(client instanceof Binder)) { // If client is not an instance of Binder - it's a remote call and at this point it is // safe to recycle the object. All objects used for local calls will be recycled after // the transaction is executed on client in ActivityThread. transaction.recycle(); }}
接着会走到
##ActivityThread.ApplicationTreadpublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException { //ActivityThread.this 指的是父类ClientTransactionHandler ActivityThread.this.scheduleTransaction(transaction);}##ClientTransactionHandlervoid scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); //发送Handler消息 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}
在handleMessage方法中处理的EXECUTE_TRANSACTION这条消息。
##ActivityThread.Hpublic void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { ... case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; //开始执行 mTransactionExecutor.execute(transaction); if (isSystem()) { // Client transactions inside system process are recycled on the client side // instead of ClientLifecycleManager to avoid being cleared before this // message is handled. transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break; ... } ...}
接着看execute方法。
##TransactionExecutorpublic void execute(ClientTransaction transaction) { final IBinder token = transaction.getActivityToken(); log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token); executeCallbacks(transaction); //1 executeLifecycleState(transaction); //5 mPendingActions.clear(); log("End resolving transaction");}##TransactionExecutorpublic void executeCallbacks(ClientTransaction transaction) { final List callbacks = transaction.getCallbacks(); //2 ... for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i); //3 ... item.execute(mTransactionHandler, token, mPendingActions); //4 ... }}
executeCallbacks方法,注释1执行回调。注释2获取到ClientTransaction中的ClientTransactionItem集合。注释3处理回调,这里获取到的ClientTransactionItem是LaunchActivityItem。注释4调用LaunchActivityItem中的execute方法。注释5是执行生命周期状态的改变,这里没有给小伙伴们贴出代码,感兴趣的小伙伴去看看。举个例子,比如Activity首次创建,默认的生命周期状态是ON_CREATE,再进行完onCreate方法调用结束后,生命周期状态值会往后移,也就是状态改变成ON_START,onStart方法调用结束,状态改变成ON_RESUME。
##LaunchActivityItempublic void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { ... client.handleLaunchActivity(r, pendingActions, null /* customIntent */); //1 ...}
execute方法中,ClientTransactionHandler是个抽象类,他的子类是ActivityThread。接着调用到的是
ActivityThread中的handleLaunchActivity方法。
##ActivityThreadpublic Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... //开始执行 final Activity a = performLaunchActivity(r, customIntent); //1 ... return a;}
注释1,开始执行启动Activity的创建。
##ActivityThreadprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; //1 ... ContextImpl appContext = createBaseContextForActivity(r); //2 Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //3 activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); //4 ... } catch (Exception e) { ... } ... //调用Activity的OnCreate()方法 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //5 } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ... return activity;}
performLaunchActivity方法中,注释1获取Activity信息。 注释2获取Activity 上下文。注释3获取到ClassLoader 类加载器对象。注释4使用ClassLoader(类加载器)加载出Activity,再使用反射new出Activity。注释5调用Activity的onCreate方法。
##Instrumentationpublic void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); activity.performCreate(icicle); //1 postPerformCreate(activity);}
注释1处,调用Activity中performCreate方法
##Activityfinal void performCreate(Bundle icicle) { performCreate(icicle, null);}##Activityfinal void performCreate(Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true; restoreHasCurrentPermissionRequest(icicle); //onCreate 生命周期方法被调用 if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ...}
performCreate方法中会调用onCreate方法。到这里Activity的创建已经结束啦。
备注:文中Android源码版本9.0