担保公司网站建设汇报,网络广告策划书案例,利用云服务器做网站,深圳网站建设 site一. Activity生命周期 1.1 返回栈知识点
二. Activity状态 2.1 启动状态 2.2 运行状态 2.3 暂停状态 2.4 停止状态 2.5 销毁状态
三. Activity生存期 3.1 回调方法 3.2 生存期
四. 体验Activity的生命周期
五. Activity被回收办法 引言#xff1a;
掌握Acti…一. Activity生命周期 1.1 返回栈知识点
二. Activity状态 2.1 启动状态 2.2 运行状态 2.3 暂停状态 2.4 停止状态 2.5 销毁状态
三. Activity生存期 3.1 回调方法 3.2 生存期
四. 体验Activity的生命周期
五. Activity被回收办法 引言
掌握Activity的生命周期对Android开发来说非常重要当我们深入理解Activity的生命周期之后就可以写出更加连贯流畅的理序并在如何合理管理应用资源方面发挥得游刃有余。我们的应用程序也将会拥有更好的用户体验。
一.Activity生命周期
1.1返回栈
我们知道Android里的Activity可以层叠的我们每启动一个新的Activity就会覆盖在原来的Activity之上然后点击Back按键会销毁最上面的Activity下面的一个Activity就会显示出来。
其实Android是使用任务(task)来管理Activity的一个任务就是一组存放在栈里的Activity的集合这个栈也被称作返回栈(back stack)。栈是一种后进先出的数据结构在默认情况下每当我们启动了一个新的Activity它就会在返回栈中入栈并处于栈顶的位置。而每当我们按下Back键或调用finish方法去销毁一个Activity时处于栈顶的Activity就会出栈前一个入栈的Activity就会重新处于栈顶的位置。
系统总是会显示处于栈顶的Activity给用户。 图1返回栈流程图
1.2 Activity状态
Activity有主要的四个状态以及一个非常迅速的启动状态下面我们来讲解他们的功能
1.2.1启动状态(Starting)
启动状态就是内个非常迅速的状态在Activity启动时会自动跳转到下一个状态这也就是为什么很多的Activity介绍里只写了四个状态而没有介绍这个状态了。
1.2.2运行状态(Running)
当一个Activity位于返回栈的栈顶时Activity就处于运行状态。系统最不愿意回收的就是处于运行状态的Activity因为这会带来非常差的运行体验。
1.2.3暂停状态(Paused)
当一个Activity不再处于栈顶的位置但仍然可见时Activity就进入了暂停状态。你可能会觉得既然Activity已经不在栈顶了怎么会可见呢这是因为并不是每一个Activity都会占满整个屏幕比如对话框式的Activity只会占用中间屏幕的部分区域。处于暂停状态的Activity仍然是完全存活的系统也不愿意回收这种Activity因为它还是可见的回收可见的东西都会在用户体验方面有不好的影响只有在内存极低的情况下系统才会去考虑回收这种Activity。
1.2.4停止状态(Stopped):
当一个Activity 不再处于栈顶位置并且完全不可见的时候就进人了停止状态。系统仍然会为这种Activity保存相应的状态和成员变量但是这并不是完全可靠的当其他地方需要内存时处于停止状态的Activity有可能会被系统回收。
1.2.5销毁状态(Destroyed):
一个Activity 从返回栈中移除后就变成了销毁状态。系统最倾向于回收处于这种状态的Activity以保证手机的内存充足。 图 2 状态关系图 1.3生存期 1.3.1回调方法 在Activity类中定义了7个回调方法其覆盖了Activity生命周期的每一个环节下面我们来一个一个看这 些方法 1.onCreate()——创建 这个方法我们已经看到过很多次了在每个Activity 中都重写了这个方法它会在Activity第一次被创建的时候调用。我们应该在这个方法中完成Activity的初始化操作比如加载布局、绑定事件等。 2.onStart()——启动 这个方法在Activity由不可见变为可见的时候调用 3.onResume()——恢复 这个方法在Activity准备好和用户进行交互的时候调用。此时的Activity一定位于返回栈的栈顶并且处于运行状态。 4.onPause()——停顿 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉以及保存一些关键数据但这个方法的执行速度一定要快不然会影响到新的栈顶Activity的使用。 5.onStop()——暂停 这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于如果启动的新Activity是一个对话框式的Activity那么onPause方法会得到执行而onstop()方法并不会执行。 6.onDestory()——销毁 这个方法在Activity被销毁之前调用之后Activity的状态将变为销毁状态。 7.onRestart——重启 这个方法在Activity由停止状态变为运行状态之前调用也就是Activity被重新启动了。 1.3.2生存期 1.3.2.1完整生存期 完整生存期Activity在onCreate()方法和onDestroy()方法之间所经历的就是完整生存期。一般情况下, 一个Activity会在onCreate()方法中完成各种初始化操作而在onDestroy()方法中完成释放内存的操 作。 1.3.2.2可见生存期 Activity在onStart()方法和onStop(方法之间所经历的就是可见生存期。在可见生存期内Activity对于用户总是可见的即便有可能无法和用户进行交互。我们可以通过这两个方法合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载而onStop()方法中对资源进行释放从而保证处于停止状态的Activity不会占用过多内存。 1.3.2.3前台生存期 Activity在onResume(方法和onPause方法之间所经历的就是前台生存期。在前台生存期内 Actvity总是处于运行状态此时的 Activity 是可以和用户进行交互的我们平时看到和接触最多的就是这个状态下的Activity。 图3.Activity生命周期 1.4体验Activity的生命周期 了解了Activity的生命周期之后我们来写一个实例通过实例来详细了解。 首先我们新建一个EmptyActivity名为NormalActivity其布局起名为normal_layout使用相同的方法创建DialogActivity布局起名为dialog_layout。 接下来我们先编辑normal_layout.xml文件。 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:orientationvertical android:layout_widthmatch_ parent android:layout_heightmatch_ parent Textview android:Layout_widthmatch_parent android:layout_heightwrap_content android:textThis is a normal activity / /LinearLayout 在这里我们简单的定义了一个TextView显示了一行文字This is a normal activity。 接着我们编辑dialog_layout.xml文件代码如下 LinearLayout xmlns:android-http://schemas.android.com/apk/res/android android:orientationvertical android: Layout_widthmatch_parent android: layout_heightmatch_parent Textview android:layout_widthmatch_parent android: layout_heightwrap_content android:textThis is a dialog activity / /LinearLayout 接下来我们修改AndroidManifest.xml的标签配件。 activity android : name .DialogActivity android : theme style/Animation.Design.BottomSheetDialog / activity activity android : name .NormalActivity android : exported false / 这里注册了两个Activity此时我们为什么使用了一个android:theme的属性这里是给前面的Activity指定主题这里的style/Animation.Design.BottomSheetDialog则毫无疑问是让DialogActivity使用对话框的主题。现在我们可以修改activity_main.xml: ?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:orientationvertical android:layout_widthmatch_parent android:layout_heightwrap_content Button android:layout_widthmatch_parent android:layout_heightwrap_content android:idid/startNormalActivity android:textStart NormalActivity/ Button android:layout_widthmatch_parent android:layout_heightwrap_content android:idid/startDialogActivity android:textStart DialogActivity/ /LinearLayout 这里我们添加两个按钮一个用于启动NormalActivity一个用于启动DialogActivity修改代码 import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private static final String TAG MainActivity; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, onCreate); setContentView(R.layout.activity_main); findViewById(R.id.startNormalActivity).setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { Intent intent new Intent(MainActivity.this, NormalActivity.class); startActivity(intent); } }); findViewById(R.id.startDialogActivity).setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { Intent intent new Intent(MainActivity.this, DialogActivity.class); startActivity(intent); } }); } Override protected void onStart() { super.onStart(); Log.d(TAG, onStart); } Override protected void onResume() { super.onResume(); Log.d(TAG, onResume); } Override protected void onPause() { super.onPause(); Log.d(TAG, onPause); } Override protected void onStop() { super.onStop(); Log.d(TAG, onStop); } Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, onDestroy); } } 现在我们启动程序并看一下logcat的效果。 图4Main界面图 此时我们不对界面做任何操作看log cat运行过程 图5MainLogCat打印日志 这里其实我们就会发现在MainActivity第一次被创建时会依次执行onCreateonStart和onResume方法。 然后点击第一个按钮NormalActivity打开normal_layout界面 图6NormalActivity界面 此时的Logcat打印日志 图7NormalActivity的LogCat打印日志 由于此时NormalActivity已经把MainActivity完全遮挡住所以onPause和onStop都会执行。然后按下Back按键返回MainActivity。 这时候我们返回原来的界面再看log cat打印日志 图8返回MainActivity时的打印日志 由于之前的MainActivity已经进入了停止状态所以onRestart方法会得到执行之后会依次执行 onRestart和onResume方法此时onCreate方法不会执行因为MainActivity并没有重新创建。 点击第二个按钮启动DialogActivity。 此时的logcat: 图9打开DialogActivity界面 可以看到只有onPause的方法得到了执行onStop没有得到执行这是因为DialogActivity并没有完全遮挡住MainActivity此时MainActivity只是进入暂停状态并没有进入停止状态。 最后在MainActivity按下Back按键退出程序打印程序 图10结束界面 1.5Activity被回收办法 前面讲过当一个Activity进入了停止状态是有可能被系统回收的。我们可以假设一种情况有一个ActivityA我们在这个基础上启动了ActivityB这时候A任务就陷入停止状态这个时候由于系统的内存不足系统将ActivityA回收掉了然后用户按下Back按键返回ActivityA正常情况下还是会显示ActivityA这是并不会执行onRestart方法而是会执行onCreate方法因为A在这种情况下被重新创建一次。 但是偶尔我们还是回遇见一种情况如果在A中可能会存在临时数据和状态比如说A里有一个文本输入框我们输入了一段数据拿上面内个程序举例此时我们打开了NormalActivity这时MainActivity由于内存不足被回收掉此时我们如果点击Back返回此时如果内存不足的话刚刚输入的文字就都没了因为MainActivity被重建了。 这种情况是非常影响用户体验的这时Activity里有一种回调方法我们就可以使用了——onSaveInstanceState这个方法可以保证在Activity被回收之前一定会被调用。 omSaveInstanceState()方法携带一个Bundle类的参数Bundle提供一系列的方法用于保存数据比如可以使用putString()方法保存字符串使用putInt()方法保存整型数据以此类推。每个保存方法需传入两个参数第一个参数是键用于后面的Bundle中取值第二个参数是真正要保存到内容。 Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); String tempData Something you just typed; outState.putString(data_key, tempData); } 数据已经保存下来了那么我们在哪里恢复呢我们一直使用的onCreate方法其实也有一个Bundle类型的参数。这个参数在一般情况下都是null。但是如果在Activity被系统回收之前我们通过 onSaveInstanceState方法保存数据这个参数就会带有之前的保存的数据我们只需要通过相应的取值方法将数据去除修改代码如下 import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; public class MyActivity extends AppCompatActivity { private static final String TAG MyActivity; // 确保你有一个合适的TAG super.onCreate(savedInstanceState); Log.d(TAG, onCreate); setContentView(R.layout.activity_main); if (savedInstanceState ! null) { String tempData savedInstanceState.getString(data_key); Log.d(TAG, tempData is tempData); } } } 取出值之后再做相应的恢复操作就可以了。 我们会发现在使用Bundle保存和取出数据的时候和使用Intent传递 也有类似的方法。这里Intent还可以结合Bundle一起用于传递数据。 首先我们可以把传递的数据都保存在Bundle对象中,然后再将Bundle对象存放在Intent里到了目标的Activity之后先从Intent中取出Bundle再从Bundle中一一取出数据。 注另外当手机的屏幕旋转的时候Activity也会有一个重建的过程所以这时候数据也可能发生丢失的情况。