Android进阶之深入理解Activity生命周期源码

移动开发 Android
Activity是一个很重要、很复杂的组件,他的启动不像我们平时直接new一个对象就完事了,他需要经历一系列的初始化。

[[419143]]

前言

Activity是一个很重要、很复杂的组件,他的启动不像我们平时直接new一个对象就完事了,他需要经历一系列的初始化。例如"刚创建状态",“后台状态”,“可见状态”等等;

当我们在界面之间进行切换的时候,activity也会在多种状态之间进行切换,可见或者不可见状态、前台或者后台状态。当Activity在不同的状态之间切换时,会回调不同的生命周期方法;

今天我们就来总结下Activity生命周期;

一、生命周期

Activity个状态生命周期流程图

由上图可知:

1.Starting -> Running,执行的生命周期顺序 onCreate()->onstart()->onResume(),

此activity所处于任务栈的top中,可以与用户进行交互。

2.Running -> Paused ,执行Activity生命周期中的onPause(),

该Activity已失去了焦点但仍然是可见的状态(包括部分可见)。就比如弹出DialogActivity

3.Paused -> Running,执行Activity生命周期中的onResume(),

此情况用户操作[home键],然后重新回到当前activity界面,还有就是关闭DialogActivity

1.Activity1 跳转至 Activity2 执行的生命周期:

  1. Activity1:onPause 
  2. Activity2:onCreate 
  3. Activity2:onStart 
  4. Activity2:onResume 
  5. Activity1:onStop 

2.Activity2回到Activity1 执行的生命周期:

  1. Activity2:onPause 
  2. Activity1:onRestart 
  3. Activity1:onStart 
  4. Activity1:onResume 
  5. Activity2:onStop 
  6. Activity2:onDestory 

3. LifeCycleActivity弹出DialogActivity 执行的生命周期:

  1. LifeCycleActivity:onPause 
  2. DialogActivity:onCreate 
  3. DialogActivity:onStart 
  4. DialogActivity:onResume 
  5. 值得注意的是:这里 LifeCycleActivity不会进入onStop,因为弹出DialogActivity时LifeCycleActivity还处于可见 

4.DialogActivity返回键到LifeCycleActivity执行的生命周期:

  1. DialogActivity:onPause 
  2. LifeCycleActivity:onResume 
  3. DialogActivity:onStop 
  4. DialogActivity:onDestroy 

5.LifeCycleActivity旋转屏幕执行的生命周期:

  1. LifeCycleActivity:onPause 
  2. LifeCycleActivity:onStop 
  3. LifeCycleActivity:onDestroy 
  4. LifeCycleActivity:onCreate 
  5. LifeCycleActivity:onStart 
  6. LifeCycleActivity:onResume 
  7. 这里相当于重新创建了Activity 

6.Activity横竖屏切换状态保存:

当前ViewPager有三个Fragment,在竖屏时选择的Fragment为第二个,如何在切换横屏后选中第二个Fragment并且Fragment保持之前的状态?

由于onCreate可以拿到保持状态的Bundle,而每次onPause以及onStop都会回调onSaveInstanceState(Bundle outState)方法;

所以可在该方法就行保存状态,大体代码如下:

  1. @Override 
  2. protected void onCreate(Bundle savedInstanceState) { 
  3.         super.onCreate(savedInstanceState); 
  4.         setContentView(R.layout.activity_main); 
  5.         // 初始化主页fragment 
  6.         if (savedInstanceState != null) { 
  7.             //系统回收后重新进入当前页面恢复数据 
  8.             resumeFragment(getSupportFragmentManager(), savedInstanceState); 
  9.             resumeIndex(savedInstanceState); 
  10.             showSelectFragmentOnly(getSupportFragmentManager()); 
  11.             mTabLayout.setCurrentItem(mIndex); 
  12.         } else { 
  13.             //正常初始化 
  14.             mTabLayout.setCurrentItem(0); 
  15.             showFragment(getSupportFragmentManager(), 0); 
  16.             mIndex=0; 
  17.         } 
  18.     } 
  19.    private void resumeFragment(FragmentManager fragmentManager, Bundle savedInstanceState) { 
  20.         Fragment[] fragments = new Fragment[fragmentTab.length]; 
  21.         for (int i = 0; i < fragments.length; i++) { 
  22.             fragments[i] = fragmentManager.getFragment(savedInstanceState, fragmentTab[i].getSimpleName()); 
  23.         } 
  24.         mFragments = fragments; 
  25.     } 
  26.     private void resumeIndex(Bundle savedInstanceState) { 
  27.         mIndex = savedInstanceState.getInt(CURRENT_INDEX, 0); 
  28.     } 
  29.   @Override 
  30.     protected void onSaveInstanceState(Bundle outState) { 
  31.         super.onSaveInstanceState(outState); 
  32.         for (Fragment fragment : mFragments) { 
  33.             if (fragment != null) { 
  34.                 getSupportFragmentManager().putFragment(outState, fragment.getClass().getName(), fragment); 
  35.             } 
  36.         } 
  37.         outState.putInt(CURRENT_INDEX, mIndex); 
  38.     } 

下图概括了android生命周期的各个环节,描述了activity从生成到销毁的过程

  • 创建:onCreate():
  • |---可用于初始化工作,如setContentView界面资源、初始化数据
  • 启动:onStart():
  • |---可见但无法交互
  • 恢复:onResume():
  • |---恢复播放动画、音乐、视频等
  • 暂停:onPause():
  • |---可做数据存储、停止动画、音乐、视频等
  • 停止:onStop():
  • |---此时Activity不可见,可做视情况做些重量级回收工作,避免被Killed
  • 销毁:onDestroy():
  • |---回收工作、资源释放
  • 重现:onRestart():
  • |---可做一些恢复工作

二、Activity基本结构

  • 一个应用程序通常由多个Activity组成,那么在应用程序中肯定需要一个容器来盛放这些Activity,必要时通过该容器找到对应的Activity,并进行相关操作。上一篇文章已经讲过一个应用程序对应一个ActivityThread,所以自然而然地该容器是ActivityThread在负责维护,这个容器叫做mActivities,是一个数组,里面的每一项叫做ActivityRecord,一个ActivityRecord对应一个Activity。
  • 以上仅仅是应用级别的管理容器,但是很多场景下,系统需要找到某一个特定的Activity,并下发相关数据比如事件分发。所以还必须在系统层面再维护一个容器,这个容器存放在Activity Manager Service,对应的容器叫做mHistory,对应的每一项叫做HistroyRecord。
  • 每个Activity必须依靠在进程中,每个进程对应一个AMS中的ProcessRecord,通过这个ProcessRecord可以找到对应的应用的所有Activity,同时还提供了与Activity联系的接口IActivityThread。
  • 所以整个Activity的管理框架如下图所示:

三.生命周期源码详解

在Launch Activity时,AMS将对应的HistoryRecord作为token传递到客服端和客服端的Activity建立联系。在AMS中Activity状态变化时,将通过该联系找到客服端的Activity,从而将消息或者动作传递应用程序面对的接口:xxxActivity。整个Activity的启动过程大致可以分为以下几个步骤:

发起startActivity(intent)请求

AMS接收到请求后,创建一个HistroyRecord对象,并将该对象放到mHistory数组中

调用app.thread.scheduleLaunchActivity()

AMS创建ActivityRecord对象,将创建的Activity放入到ActivityRecord,再将其放入到mActivities

发起Activity的onCreate()方法

1、Activty是如何创建?ActivityThread 便是这关键

  1. public final class ActivityThread { 
  2.    Instrumentation mInstrumentation; 
  3.     ...... 
  4.     final ApplicationThread mAppThread = new ApplicationThread(); 
  5.    // Looper类创建 
  6.     final Looper mLooper = Looper.myLooper(); 
  7.    // H是继承Handler类 在AcivityThread创建时就创建了 
  8.     final H mH = new H(); 
  9.    ...... 

H类源码如下:

  1. private class H extends Handler { 
  2. ........ 
  3.  public void handleMessage(Message msg) { 
  4.             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 
  5.             switch (msg.what) { 
  6.                 case LAUNCH_ACTIVITY: { 
  7.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 
  8.                     final ActivityClientRecord r = (ActivityClientRecord) msg.obj; 
  9.                     r.packageInfo = getPackageInfoNoCheck( 
  10.                             r.activityInfo.applicationInfo, r.compatInfo); 
  11.                     handleLaunchActivity(r, null"LAUNCH_ACTIVITY"); 
  12.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  13.                 } break; 
  14.                 case RELAUNCH_ACTIVITY: { 
  15.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 
  16.                     ActivityClientRecord r = (ActivityClientRecord)msg.obj; 
  17.                     handleRelaunchActivity(r); 
  18.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  19.                 } break; 
  20.                 case PAUSE_ACTIVITY: { 
  21.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 
  22.                     SomeArgs args = (SomeArgs) msg.obj; 
  23.                     handlePauseActivity((IBinder) args.arg1, false
  24.                             (args.argi1 & USER_LEAVING) != 0, args.argi2, 
  25.                             (args.argi1 & DONT_REPORT) != 0, args.argi3); 
  26.                     maybeSnapshot(); 
  27.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  28.                 } break; 
  29.                 case PAUSE_ACTIVITY_FINISHING: { 
  30.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 
  31.                     SomeArgs args = (SomeArgs) msg.obj; 
  32.                     handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0, 
  33.                             args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); 
  34.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  35.                 } break; 
  36.                 case STOP_ACTIVITY_SHOW: { 
  37.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 
  38.                     SomeArgs args = (SomeArgs) msg.obj; 
  39.                     handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3); 
  40.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  41.                 } break; 
  42.                 case STOP_ACTIVITY_HIDE: { 
  43.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 
  44.                     SomeArgs args = (SomeArgs) msg.obj; 
  45.                     handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3); 
  46.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  47.                 } break; 
  48.                 case SHOW_WINDOW: 
  49.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow"); 
  50.                     handleWindowVisibility((IBinder)msg.obj, true); 
  51.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  52.                     break; 
  53.                 case HIDE_WINDOW: 
  54.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow"); 
  55.                     handleWindowVisibility((IBinder)msg.obj, false); 
  56.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  57.                     break; 
  58.                 case RESUME_ACTIVITY: 
  59.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); 
  60.                     SomeArgs args = (SomeArgs) msg.obj; 
  61.                     handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true
  62.                             args.argi3, "RESUME_ACTIVITY"); 
  63.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  64.                     break; 
  65.                 case SEND_RESULT: 
  66.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult"); 
  67.                     handleSendResult((ResultData)msg.obj); 
  68.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  69.                     break; 
  70.                 case DESTROY_ACTIVITY: 
  71.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy"); 
  72.                     handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, 
  73.                             msg.arg2, false); 
  74.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  75.                     break; 
  76. ......... 
  77.         } 

那么H类handleMessage是怎么被调用的呢?其实是通过ApplicationThread的scheduleLaunchActivity来完成的,这里ApplicationThread是ActivtyThread的内部类

ApplicationThread部分源码如下:

  1. private class ApplicationThread extends IApplicationThread.Stub { 
  2.         ........省略...... 
  3.         public final void schedulePauseActivity(IBinder token, boolean finished, 
  4.                 boolean userLeaving, int configChanges, boolean dontReport) { 
  5.             int seq = getLifecycleSeq(); 
  6.             if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this 
  7.                     + " operation received seq: " + seq); 
  8.             sendMessage( 
  9.                     finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 
  10.                     token, 
  11.                     (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), 
  12.                     configChanges, 
  13.                     seq); 
  14.         } 
  15.         public final void scheduleStopActivity(IBinder token, boolean showWindow, 
  16.                 int configChanges) { 
  17.             int seq = getLifecycleSeq(); 
  18.             if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this 
  19.                     + " operation received seq: " + seq); 
  20.             sendMessage( 
  21.                 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 
  22.                 token, 0, configChanges, seq); 
  23.         } 
  24.         public final void scheduleWindowVisibility(IBinder token, boolean showWindow) { 
  25.             sendMessage( 
  26.                 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW, 
  27.                 token); 
  28.         } 
  29.         public final void scheduleSleeping(IBinder token, boolean sleeping) { 
  30.             sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 
  31.         } 
  32.         public final void scheduleResumeActivity(IBinder token, int processState, 
  33.                 boolean isForward, Bundle resumeArgs) { 
  34.             int seq = getLifecycleSeq(); 
  35.             if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this 
  36.                     + " operation received seq: " + seq); 
  37.             updateProcessState(processState, false); 
  38.             sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq); 
  39.         } 
  40.         public final void scheduleSendResult(IBinder token, List<ResultInfo> results) { 
  41.             ResultData res = new ResultData(); 
  42.             res.token = token; 
  43.             res.results = results; 
  44.             sendMessage(H.SEND_RESULT, res); 
  45.         } 
  46.         // AMS通过调用此方法启动Activity 
  47.         @Override 
  48.         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 
  49.                 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 
  50.                 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 
  51.                 int procState, Bundle state, PersistableBundle persistentState, 
  52.                 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 
  53.                 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 
  54.             updateProcessState(procState, false); 
  55.             ActivityClientRecord r = new ActivityClientRecord(); 
  56.             r.token = token; 
  57.             r.ident = ident; 
  58.             r.intent = intent; 
  59.             r.referrer = referrer; 
  60.             r.voiceInteractor = voiceInteractor; 
  61.             r.activityInfo = info; 
  62.             r.compatInfo = compatInfo; 
  63.             r.state = state; 
  64.             r.persistentState = persistentState; 
  65.             r.pendingResults = pendingResults; 
  66.             r.pendingIntents = pendingNewIntents; 
  67.             r.startsNotResumed = notResumed; 
  68.             r.isForward = isForward; 
  69.             r.profilerInfo = profilerInfo; 
  70.             r.overrideConfig = overrideConfig; 
  71.             updatePendingConfiguration(curConfig); 
  72.             sendMessage(H.LAUNCH_ACTIVITY, r); 
  73.         } 
  74.       ........省略...... 

2、那么ActivtyThread是如何初始化的?

通过主入口函数main方法进行初始化:

  1. public static void main(String[] args) { 
  2.         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 
  3.         SamplingProfilerIntegration.start(); 
  4.         CloseGuard.setEnabled(false); 
  5.         Environment.initForCurrentUser(); 
  6.         EventLogger.setReporter(new EventLoggingReporter()); 
  7.         final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 
  8.         TrustedCertificateStore.setDefaultUserDirectory(configDir); 
  9.         Process.setArgV0("<pre-initialized>"); 
  10.         Looper.prepareMainLooper(); 
  11. // 初始化ActivityThread  
  12.         ActivityThread thread = new ActivityThread(); 
  13.         thread.attach(false); 
  14.         if (sMainThreadHandler == null) { 
  15.             sMainThreadHandler = thread.getHandler(); 
  16.         } 
  17.         if (false) { 
  18.             Looper.myLooper().setMessageLogging(new 
  19.                     LogPrinter(Log.DEBUG, "ActivityThread")); 
  20.         } 
  21.         // End of event ActivityThreadMain. 
  22.         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  23.         Looper.loop(); 
  24.         throw new RuntimeException("Main thread loop unexpectedly exited"); 
  25.     } 

3、ApplicationThread的scheduleLaunchActivity是如何被调用的?

在上述代码中我们看到ActivtyThread初始化后调用了attach方法

  1. private void attach(boolean system) { 
  2.         sCurrentActivityThread = this; 
  3.         mSystemThread = system; 
  4.         if (!system) { 
  5.             ViewRootImpl.addFirstDrawHandler(new Runnable() { 
  6.                 @Override 
  7.                 public void run() { 
  8.                     ensureJitEnabled(); 
  9.                 } 
  10.             }); 
  11.             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>"
  12.                                                     UserHandle.myUserId()); 
  13.             RuntimeInit.setApplicationObject(mAppThread.asBinder()); 
  14.             final IActivityManager mgr = ActivityManager.getService(); 
  15.             try { 
  16. // 调用scheduleLaunchActivity的关键代码 
  17.                 mgr.attachApplication(mAppThread); 
  18.             } catch (RemoteException ex) { 
  19.                 throw ex.rethrowFromSystemServer(); 
  20.             } 
  21.             // Watch for getting close to heap limit. 
  22.             BinderInternal.addGcWatcher(new Runnable() { 
  23.                 @Override public void run() { 
  24.                     if (!mSomeActivitiesChanged) { 
  25.                         return
  26.                     } 
  27.                     Runtime runtime = Runtime.getRuntime(); 
  28.                     long dalvikMax = runtime.maxMemory(); 
  29.                     long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 
  30.                     if (dalvikUsed > ((3*dalvikMax)/4)) { 
  31.                         if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 
  32.                                 + " total=" + (runtime.totalMemory()/1024) 
  33.                                 + " used=" + (dalvikUsed/1024)); 
  34.                         mSomeActivitiesChanged = false
  35.                         try { 
  36.                             mgr.releaseSomeActivities(mAppThread); 
  37.                         } catch (RemoteException e) { 
  38.                             throw e.rethrowFromSystemServer(); 
  39.                         } 
  40.                     } 
  41.                 } 
  42.             }); 
  43.         } else { 
  44.          // 这里是系统服务初始化的,在SystemServer类中main方法进行调用 
  45.             android.ddm.DdmHandleAppName.setAppName("system_process"
  46.                     UserHandle.myUserId()); 
  47.             try { 
  48.                 mInstrumentation = new Instrumentation(); 
  49.                 ContextImpl context = ContextImpl.createAppContext( 
  50.                         this, getSystemContext().mPackageInfo); 
  51.                 mInitialApplication = context.mPackageInfo.makeApplication(truenull); 
  52.                 mInitialApplication.onCreate(); 
  53.             } catch (Exception e) { 
  54.                 throw new RuntimeException( 
  55.                         "Unable to instantiate Application():" + e.toString(), e); 
  56.             } 
  57.         } 
  58.         // add dropbox logging to libcore 
  59.         DropBox.setReporter(new DropBoxReporter()); 
  60.         ViewRootImpl.ConfigChangedCallback configChangedCallback 
  61.                 = (Configuration globalConfig) -> { 
  62.             synchronized (mResourcesManager) { 
  63.                 // We need to apply this change to the resources immediately, because upon returning 
  64.                 // the view hierarchy will be informed about it. 
  65.                 if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, 
  66.                         null /* compat */)) { 
  67.                     updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 
  68.                             mResourcesManager.getConfiguration().getLocales()); 
  69.                     // This actually changed the resources! Tell everyone about it. 
  70.                     if (mPendingConfiguration == null 
  71.                             || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { 
  72.                         mPendingConfiguration = globalConfig; 
  73.                         sendMessage(H.CONFIGURATION_CHANGED, globalConfig); 
  74.                     } 
  75.                 } 
  76.             } 
  77.         }; 
  78.         ViewRootImpl.addConfigCallback(configChangedCallback); 
  79.     } 

上述代码中IActivityManager是一个接口而他的实现类就是大名鼎鼎的

  1. ActivityManagerService(AMS),我们来看AMS中对attachApplication的实现: 
  2.     @Override 
  3.     public final void attachApplication(IApplicationThread thread) { 
  4. // ApplicationThread 实现了IApplicationThread的接口 
  5.         synchronized (this) { 
  6.             int callingPid = Binder.getCallingPid(); 
  7.             final long origId = Binder.clearCallingIdentity(); 
  8.             attachApplicationLocked(thread, callingPid); 
  9.             Binder.restoreCallingIdentity(origId); 
  10.         } 
  11.     } 

attachApplicationLocked方法中调用了ActivityStackSupervisor中的attachApplicationLocked方法,而该方法中调用了ApplicationThread中scheduleLaunchActivity,有兴趣的可以去看下源码。

我们可以发现其实不管是scheduleLaunchActivity还是其他的schedule...方法都调用了ApplicationThread中的sendMessage方法,该方法如下:

  1. private void sendMessage(int what, Object obj) { 
  2.         sendMessage(what, obj, 0, 0, false); 
  3.     } 
  4.     private void sendMessage(int what, Object obj, int arg1) { 
  5.         sendMessage(what, obj, arg1, 0, false); 
  6.     } 
  7.     private void sendMessage(int what, Object obj, int arg1, int arg2) { 
  8.         sendMessage(what, obj, arg1, arg2, false); 
  9.     } 
  10.     private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 
  11.         if (DEBUG_MESSAGES) Slog.v( 
  12.             TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 
  13.             + ": " + arg1 + " / " + obj); 
  14.         Message msg = Message.obtain(); 
  15.         msg.what = what; 
  16.         msg.obj = obj; 
  17.         msg.arg1 = arg1; 
  18.         msg.arg2 = arg2; 
  19.         if (async) { 
  20.             msg.setAsynchronous(true); 
  21.         } 
  22.         mH.sendMessage(msg); 
  23.     } 

我们方法转了一圈依旧回到了handler.sendMessage()方法,可见handler在Android中的重要性;

4、如何处理Handler发送的消息呢?

通过handleMessage进行处理,所有的生命周期其实都是通过该方法处理的,源码如下:

  1. public void handleMessage(Message msg) { 
  2. ......省略..... 
  3.             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 
  4.             switch (msg.what) { 
  5.                 case LAUNCH_ACTIVITY: { 
  6.                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 
  7.                     final ActivityClientRecord r = (ActivityClientRecord) msg.obj; 
  8.                     r.packageInfo = getPackageInfoNoCheck( 
  9.                             r.activityInfo.applicationInfo, r.compatInfo); 
  10.                     handleLaunchActivity(r, null"LAUNCH_ACTIVITY"); 
  11.                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
  12.                 } break; 
  13.       } 
  14. ......省略..... 

Looper会循环获取messageQueue队列中的message,并通过dispatchMessage多消息进行分发,源码如下:

  1. public void dispatchMessage(Message msg) { 
  2.        if (msg.callback != null) { 
  3.            handleCallback(msg); 
  4.        } else { 
  5.            if (mCallback != null) { 
  6.                if (mCallback.handleMessage(msg)) { 
  7.                    return
  8.                } 
  9.            } 
  10. / 这里其实是调用了H类的handleMessage方法 
  11.            handleMessage(msg); 
  12.        } 
  13.    } 

上述代码可以看到handleMessage中的handleLaunchActivity是关键,handleLaunchActivity代码如下:

  1.  private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { 
  2.         unscheduleGcIdler(); 
  3.         mSomeActivitiesChanged = true
  4.         if (r.profilerInfo != null) { 
  5.             mProfiler.setProfiler(r.profilerInfo); 
  6.             mProfiler.startProfiling(); 
  7.         } 
  8.         handleConfigurationChanged(nullnull); 
  9.         if (localLOGV) Slog.v( 
  10.             TAG, "Handling launch of " + r); 
  11.         WindowManagerGlobal.initialize(); 
  12. // 在这里创建了application以及activity 
  13.         Activity a = performLaunchActivity(r, customIntent); 
  14.         if (a != null) { 
  15.             r.createdConfig = new Configuration(mConfiguration); 
  16.             reportSizeConfigurations(r); 
  17.             Bundle oldState = r.state; 
  18.             handleResumeActivity(r.token, false, r.isForward, 
  19.                     !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); 
  20.             if (!r.activity.mFinished && r.startsNotResumed) { 
  21.                 performPauseActivityIfNeeded(r, reason); 
  22.                 if (r.isPreHoneycomb()) { 
  23.                     r.state = oldState; 
  24.                 } 
  25.             } 
  26.         } else { 
  27.             try { 
  28.                 ActivityManager.getService() 
  29.                     .finishActivity(r.token, Activity.RESULT_CANCELED, null
  30.                             Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 
  31.             } catch (RemoteException ex) { 
  32.                 throw ex.rethrowFromSystemServer(); 
  33.             } 
  34.         } 
  35.     } 
  36.  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 
  37.         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); 
  38.         ActivityInfo aInfo = r.activityInfo; 
  39.         if (r.packageInfo == null) { 
  40.             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 
  41.                     Context.CONTEXT_INCLUDE_CODE); 
  42.         } 
  43.         ComponentName component = r.intent.getComponent(); 
  44.         if (component == null) { 
  45.             component = r.intent.resolveActivity( 
  46.                 mInitialApplication.getPackageManager()); 
  47.             r.intent.setComponent(component); 
  48.         } 
  49.         if (r.activityInfo.targetActivity != null) { 
  50.             component = new ComponentName(r.activityInfo.packageName, 
  51.                     r.activityInfo.targetActivity); 
  52.         } 
  53. // 创建context 
  54.         ContextImpl appContext = createBaseContextForActivity(r); 
  55.         Activity activity = null
  56.         try { 
  57.             java.lang.ClassLoader cl = appContext.getClassLoader(); 
  58. // activty的创建  
  59.             activity = mInstrumentation.newActivity( 
  60.                     cl, component.getClassName(), r.intent); 
  61.             StrictMode.incrementExpectedActivityCount(activity.getClass()); 
  62.             r.intent.setExtrasClassLoader(cl); 
  63.             r.intent.prepareToEnterProcess(); 
  64.             if (r.state != null) { 
  65.                 r.state.setClassLoader(cl); 
  66.             } 
  67.         } catch (Exception e) { 
  68.             if (!mInstrumentation.onException(activity, e)) { 
  69.                 throw new RuntimeException( 
  70.                     "Unable to instantiate activity " + component 
  71.                     + ": " + e.toString(), e); 
  72.             } 
  73.         } 
  74.         try { 
  75. // application的创建 
  76.             Application app = r.packageInfo.makeApplication(false, mInstrumentation); 
  77.             if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 
  78.             if (localLOGV) Slog.v( 
  79.                     TAG, r + ": app=" + app 
  80.                     + ", appName=" + app.getPackageName() 
  81.                     + ", pkg=" + r.packageInfo.getPackageName() 
  82.                     + ", comp=" + r.intent.getComponent().toShortString() 
  83.                     + ", dir=" + r.packageInfo.getAppDir()); 
  84.             if (activity != null) { 
  85. // 从配置文件获取label作为Activity默认title 
  86.                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 
  87.                 Configuration config = new Configuration(mCompatConfiguration); 
  88.                 if (r.overrideConfig != null) { 
  89.                     config.updateFrom(r.overrideConfig); 
  90.                 } 
  91.                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 
  92.                         + r.activityInfo.name + " with config " + config); 
  93. // window的创建 
  94.                 Window window = null
  95.                 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { 
  96.                     window = r.mPendingRemoveWindow; 
  97.                     r.mPendingRemoveWindow = null
  98.                     r.mPendingRemoveWindowManager = null
  99.                 } 
  100.                 appContext.setOuterContext(activity); 
  101.                 activity.attach(appContext, this, getInstrumentation(), r.token, 
  102.                         r.ident, app, r.intent, r.activityInfo, title, r.parent, 
  103.                         r.embeddedID, r.lastNonConfigurationInstances, config, 
  104.                         r.referrer, r.voiceInteractor, window, r.configCallback); 
  105.                 if (customIntent != null) { 
  106.                     activity.mIntent = customIntent; 
  107.                 } 
  108.                 r.lastNonConfigurationInstances = null
  109.                 checkAndBlockForNetworkAccess(); 
  110.                 activity.mStartedActivity = false
  111.                 int theme = r.activityInfo.getThemeResource(); 
  112.                 if (theme != 0) { 
  113.                     activity.setTheme(theme); 
  114.                 } 
  115.                 activity.mCalled = false
  116.                 if (r.isPersistable()) { 
  117. // 触发onCreate回调 
  118.                     mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 
  119.                 } else { 
  120. // 触发onCreate回调 
  121.                     mInstrumentation.callActivityOnCreate(activity, r.state); 
  122.                 } 
  123.                 if (!activity.mCalled) { 
  124.                     throw new SuperNotCalledException( 
  125.                         "Activity " + r.intent.getComponent().toShortString() + 
  126.                         " did not call through to super.onCreate()"); 
  127.                 } 
  128.                 r.activity = activity; 
  129.                 r.stopped = true
  130.                 if (!r.activity.mFinished) { 
  131.                     activity.performStart(); 
  132.                     r.stopped = false
  133.                 } 
  134.                 if (!r.activity.mFinished) { 
  135.                     if (r.isPersistable()) { 
  136.                         if (r.state != null || r.persistentState != null) { 
  137.                             mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, 
  138.                                     r.persistentState); 
  139.                         } 
  140.                     } else if (r.state != null) { 
  141. // 其实都是调用了Activity的onPostCreate方法,该方法调用了onTitleChanged方法,用于设置title栏 
  142.                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 
  143.                     } 
  144.                 } 
  145.                 if (!r.activity.mFinished) { 
  146.                     activity.mCalled = false
  147.                     if (r.isPersistable()) { 
  148.                         mInstrumentation.callActivityOnPostCreate(activity, r.state, 
  149.                                 r.persistentState); 
  150.                     } else { 
  151.                         mInstrumentation.callActivityOnPostCreate(activity, r.state); 
  152.                     } 
  153.                     if (!activity.mCalled) { 
  154.                         throw new SuperNotCalledException( 
  155.                             "Activity " + r.intent.getComponent().toShortString() + 
  156.                             " did not call through to super.onPostCreate()"); 
  157.                     } 
  158.                 } 
  159.             } 
  160.             r.paused = true
  161.             mActivities.put(r.token, r); 
  162.         } catch (SuperNotCalledException e) { 
  163.             throw e; 
  164.         } catch (Exception e) { 
  165.             if (!mInstrumentation.onException(activity, e)) { 
  166.                 throw new RuntimeException( 
  167.                     "Unable to start activity " + component 
  168.                     + ": " + e.toString(), e); 
  169.             } 
  170.         } 
  171.         return activity; 
  172.     } 

上述代码中可以看到在performLaunchActivity中创建了上下文Context,Application,以及Activity,而后通过Activity的attach方法为Context赋值并且将Activity与Window绑定,有兴趣的可以去看下其实是为ContextWrapper中的mBase对象进行了赋值,而且Activity的attach方法中实例化了Window对象,并且设定了UI线程为当前线程,这里就不做讲解,贴出attach的源码:

  1. final void attach(Context context, ActivityThread aThread, 
  2.            Instrumentation instr, IBinder token, int ident, 
  3.            Application application, Intent intent, ActivityInfo info, 
  4.            CharSequence title, Activity parent, String id, 
  5.            NonConfigurationInstances lastNonConfigurationInstances, 
  6.            Configuration config, String referrer, IVoiceInteractor voiceInteractor, 
  7.            Window window, ActivityConfigCallback activityConfigCallback) { 
  8.        attachBaseContext(context); 
  9.        mFragments.attachHost(null /*parent*/); 
  10.        mWindow = new PhoneWindow(this, window, activityConfigCallback); 
  11.        mWindow.setWindowControllerCallback(this); 
  12.        mWindow.setCallback(this); 
  13.        mWindow.setOnWindowDismissedCallback(this); 
  14.        mWindow.getLayoutInflater().setPrivateFactory(this); 
  15.        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { 
  16.            mWindow.setSoftInputMode(info.softInputMode); 
  17.        } 
  18.        if (info.uiOptions != 0) { 
  19.            mWindow.setUiOptions(info.uiOptions); 
  20.        } 
  21.        mUiThread = Thread.currentThread(); 
  22.        mMainThread = aThread; 
  23.        mInstrumentation = instr; 
  24.        mToken = token; 
  25.        mIdent = ident; 
  26.        mApplication = application; 
  27.        mIntent = intent; 
  28.        mReferrer = referrer; 
  29.        mComponent = intent.getComponent(); 
  30.        mActivityInfo = info; 
  31.        mTitle = title; 
  32.        mParent = parent; 
  33.        mEmbeddedID = id; 
  34.        mLastNonConfigurationInstances = lastNonConfigurationInstances; 
  35.        if (voiceInteractor != null) { 
  36.            if (lastNonConfigurationInstances != null) { 
  37.                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor; 
  38.            } else { 
  39.                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this, 
  40.                        Looper.myLooper()); 
  41.            } 
  42.        } 
  43.        mWindow.setWindowManager( 
  44.                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), 
  45.                mToken, mComponent.flattenToString(), 
  46.                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); 
  47.        if (mParent != null) { 
  48.            mWindow.setContainer(mParent.getWindow()); 
  49.        } 
  50.        mWindowManager = mWindow.getWindowManager(); 
  51.        mCurrentConfig = config; 
  52.        mWindow.setColorMode(info.colorMode); 
  53.    } 

在所有生命周期回调中,都是调用了Instrumentation中的方法,而Instrumentation的调用都是通过Handler发送消息触发H函数的handleMessage方法来进行的,然后Instrumentation中的方法再去调用Activity中的生命周期方法,其实我们常用的onActivityResult回调都是通过handleMessage去分发的。Instrumentation部分代码如下

  1. // 触发onCreate 
  2.   public void callActivityOnCreate(Activity activity, Bundle icicle, 
  3.             PersistableBundle persistentState) { 
  4.         prePerformCreate(activity); 
  5.         activity.performCreate(icicle, persistentState); 
  6.         postPerformCreate(activity); 
  7.     } 
  8. // 触发onResume 
  9. public void callActivityOnResume(Activity activity) { 
  10.         activity.mResumed = true
  11.         activity.onResume(); 
  12.         if (mActivityMonitors != null) { 
  13.             synchronized (mSync) { 
  14.                 final int N = mActivityMonitors.size(); 
  15.                 for (int i=0; i<N; i++) { 
  16.                     final ActivityMonitor am = mActivityMonitors.get(i); 
  17.                     am.match(activity, activity, activity.getIntent()); 
  18.                 } 
  19.             } 
  20.         } 
  21.     } 

总结:

  • 创建一个activity会依次执行onCreate, onStart, onResume
  • 从一个activity启动另一个activity会先调用当前activity的onResume,然后在创建并显示要启动的activity。
  • 从非透明activity返回的时候会先调用当前的onPause,然后调用前一个activitiy的onRestart、onStart、onResme,然后在调用这个Activity的onStop,onDestroy。
  • 从透明的activity返回的时候会先调用当前activity的onPause,然后调用前一个activity的onResume,然后调用这个透明activity的onStop,onDestroy。
  • 透明的Activity比较特殊,他会让别的activity的一些生命周期不被调用比如onStop等待。
  • onResume方法里不能有太耗时的操作,因为当启动另一个activity的时候,当前的onResume没有返回不会去创建要启动的那个activity
  • Activity启动过程会经历两次跨进程,从App进程到AMS,从AMS再到APP进程,实际情况要远比这复杂的多;

本文转载自微信公众号「 Android开发编程 」

 

责任编辑:姜华 来源: Android开发编程
相关推荐

2021-09-08 06:51:52

AndroidRetrofit原理

2021-10-15 09:19:17

AndroidSharedPrefe分析源码

2021-09-03 07:27:38

AndroidGlide管理

2011-06-16 09:31:21

ActivityAndroid

2021-09-10 07:31:54

AndroidAppStartup原理

2021-09-30 07:36:51

AndroidViewDraw

2013-12-26 15:26:48

Android SDKActivity生命周期

2010-01-26 13:20:02

Android Act

2021-09-17 06:55:50

AndroidLayoutView

2021-09-16 06:44:04

Android进阶流程

2014-07-15 17:17:31

AdapterAndroid

2021-09-15 07:31:33

Android窗口管理

2010-07-14 10:59:15

Perl线程

2021-09-24 08:10:40

Java 语言 Java 基础

2017-08-08 09:15:41

前端JavaScript页面渲染

2010-07-28 12:47:06

Flex组件

2021-02-17 11:25:33

前端JavaScriptthis

2016-10-26 20:49:24

ReactJavascript前端

2024-08-30 10:40:12

2017-07-04 09:49:36

ActivityAndroidLife场景
点赞
收藏

51CTO技术栈公众号