Activity是一个很重要、很复杂的组件,他的启动不像我们平时直接new一个对象就完事了,他需要经历一系列的初始化。
前言
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 执行的生命周期:
Activity1:onPause Activity2:onCreate Activity2:onStart Activity2:onResume Activity1:onStop
2.Activity2回到Activity1 执行的生命周期:
Activity2:onPause Activity1:onRestart Activity1:onStart Activity1:onResume Activity2:onStop Activity2:onDestory
3. LifeCycleActivity弹出DialogActivity 执行的生命周期:
LifeCycleActivity:onPause DialogActivity:onCreate DialogActivity:onStart DialogActivity:onResume 值得注意的是:这里 LifeCycleActivity不会进入onStop,因为弹出DialogActivity时LifeCycleActivity还处于可见
4.DialogActivity返回键到LifeCycleActivity执行的生命周期:
DialogActivity:onPause LifeCycleActivity:onResume DialogActivity:onStop DialogActivity:onDestroy
5.LifeCycleActivity旋转屏幕执行的生命周期:
LifeCycleActivity:onPause LifeCycleActivity:onStop LifeCycleActivity:onDestroy LifeCycleActivity:onCreate LifeCycleActivity:onStart LifeCycleActivity:onResume 这里相当于重新创建了Activity
6.Activity横竖屏切换状态保存:
当前ViewPager有三个Fragment,在竖屏时选择的Fragment为第二个,如何在切换横屏后选中第二个Fragment并且Fragment保持之前的状态?
由于onCreate可以拿到保持状态的Bundle,而每次onPause以及onStop都会回调onSaveInstanceState(Bundle outState)方法;
所以可在该方法就行保存状态,大体代码如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化主页fragment if (savedInstanceState != null) { //系统回收后重新进入当前页面恢复数据 resumeFragment(getSupportFragmentManager(), savedInstanceState); resumeIndex(savedInstanceState); showSelectFragmentOnly(getSupportFragmentManager()); mTabLayout.setCurrentItem(mIndex); } else { //正常初始化 mTabLayout.setCurrentItem(0); showFragment(getSupportFragmentManager(), 0); mIndex=0; } } private void resumeFragment(FragmentManager fragmentManager, Bundle savedInstanceState) { Fragment[] fragments = new Fragment[fragmentTab.length]; for (int i = 0; i < fragments.length; i++) { fragments[i] = fragmentManager.getFragment(savedInstanceState, fragmentTab[i].getSimpleName()); } mFragments = fragments; } private void resumeIndex(Bundle savedInstanceState) { mIndex = savedInstanceState.getInt(CURRENT_INDEX, 0); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); for (Fragment fragment : mFragments) { if (fragment != null) { getSupportFragmentManager().putFragment(outState, fragment.getClass().getName(), fragment); } } outState.putInt(CURRENT_INDEX, mIndex); }
下图概括了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 便是这关键
public final class ActivityThread { Instrumentation mInstrumentation; ...... final ApplicationThread mAppThread = new ApplicationThread(); // Looper类创建 final Looper mLooper = Looper.myLooper(); // H是继承Handler类 在AcivityThread创建时就创建了 final H mH = new H(); ...... }
H类源码如下:
private class H extends Handler { ........ public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); SomeArgs args = (SomeArgs) msg.obj; handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY_FINISHING: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); SomeArgs args = (SomeArgs) msg.obj; handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case STOP_ACTIVITY_SHOW: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); SomeArgs args = (SomeArgs) msg.obj; handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case STOP_ACTIVITY_HIDE: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); SomeArgs args = (SomeArgs) msg.obj; handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case SHOW_WINDOW: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow"); handleWindowVisibility((IBinder)msg.obj, true); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case HIDE_WINDOW: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow"); handleWindowVisibility((IBinder)msg.obj, false); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case RESUME_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); SomeArgs args = (SomeArgs) msg.obj; handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true, args.argi3, "RESUME_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case SEND_RESULT: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult"); handleSendResult((ResultData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case DESTROY_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy"); handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, msg.arg2, false); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ......... } }
那么H类handleMessage是怎么被调用的呢?其实是通过ApplicationThread的scheduleLaunchActivity来完成的,这里ApplicationThread是ActivtyThread的内部类
ApplicationThread部分源码如下:
private class ApplicationThread extends IApplicationThread.Stub { ........省略...... public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { int seq = getLifecycleSeq(); if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this + " operation received seq: " + seq); sendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), configChanges, seq); } public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) { int seq = getLifecycleSeq(); if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this + " operation received seq: " + seq); sendMessage(
发表评论 取消回复