1.4、活动的生命周期

对于活动来说生命周期的理解时非常重要的

当对其生命周期有了足够的了解,可以很好的写出程序

1.4.1、返回栈

Android中的活动是可以层叠的

没启动一个新的活动,就会立即覆盖再原来的活动之上

点击Back就会销毁最上面的活动,上一个活动就会重新显示

Android时使用任务(Task)来管理活动的

一个任务就是一组存放在栈里的活动集合,这个栈也成为返回栈

栈是一种先进后出的数据结构

再莫瑞诺情况下,当启动一个新的活动,他会在返回栈中入栈,并且处于栈顶的位置

按下Back键的似乎或者调用finish()方法销毁一个活动,处于栈顶的活动会出栈

这时候前一个入栈的活动就会重新处于栈顶的位置。

返回栈工作示意图:

1.4.2、活动状态

每个活动在生命周期最多可能出现的4种状态

1、运行状态

当一个活动处于栈顶的时候,这个活动就处于运行状态

系统最不愿意回收的就是处于运行状态的活动,会给用户带来很差的体验

2、暂停状态

当活动不在处于栈顶的位置,但仍然可见,这个活动此时就处于暂停状态。

3、停止状态

当一个活动不在处于栈顶的位置,且完全不可见的时候,就进入了停止状态。

4、销毁状态

当一个活动从返回栈中移除后就变成了销毁状态。

系统会进行回收,保证手机内存的充足

1.4.3、活动的生命周期

Activity类中定义了七个方法

可以完全覆盖生命周期中的每一个环节:

1、onCreate()

他会在活动第一次创建的时候调用,可以实现活动的初始化:加载布局、绑定事件....

2、onStart()

这个方法是在活动由不可见变为可见的时候调用

3、onPause()

这个方法是在系统准备去启动或者恢复另一个活动的时候调用

通常用于释放资源、保存相关的数据

但是这个方法执行的速度要快,不然会影响到栈顶的活动使用

4、onStop()

在活动完全不可见的时候去调用

与onPause()方法的主要区别在于:如果启动的新活动是一个对话框式的活动,那么onPause()会执行,后者不会

5、onResume()

这个方法在获得准备好和用户进行交互的时候调用

6、onDestroy()

这个方法在活动销毁之前进行调用,之后活动的状态将变为销毁状态

7、onRestart()

这个方法在活动由停止状态变为运行状态之前调用

以上除了onRestart()方法,其他都是两两相对的

从而可以将活动分为3中生命周期

活动生命周期的示意图:

1.4.4、实践活动的生命周期

根据之前的三个项目来进行测试:

first_layout.xml

    <Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/button_first"android:text="to first"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/button_second"android:text="to second"/>

定义了两个按钮,分别在监听中跳转到其他两个页面

FirstActivity.java

实现7个方法,并且进行打印每一个方法被调用的时机来确定该方法的执行实时间

public class FirstActivity extends AppCompatActivity {@Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout);Log.d("onCreate====","onCreate");Button first = (Button) findViewById(R.id.button_first);first.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this,SecondActivity.class);startActivity(intent);}});Button second = (Button) findViewById(R.id.button_second);second.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this,ThirdActivity.class);startActivity(intent);}});}@Overrideprotected void onStart() {super.onStart();
        Log.d("onStart====","onStart");}@Overrideprotected void onResume() {super.onResume();    Log.d("onResume====","onResume");}@Overrideprotected void onPause() {super.onPause();    Log.d("onPause====","onPause");}@Overrideprotected void onStop() {super.onStop();   Log.d("onStop====","onStop");}@Overrideprotected void onDestroy() {super.onDestroy();   Log.d("onDestroy====","onDestroy");}@Overrideprotected void onRestart() {super.onRestart();
        Log.d("onRestart====","onRestart");}
}

second_activity.xml

这里仅仅只是一个页面数据显示,无其他的功能实现!!!

    <TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="this second"/>

third_activity.xml

这里仅仅只是一个页面数据显示,无其他的功能实现!!!

    <TextViewandroid:text="this is first"android:layout_width="match_parent"android:layout_height="wrap_content" />

启动:

可以直接观察看控制台的打印:

此时没有出发按钮的点击事件:

第一次创建FirstActivity活动时会一次执行onCreate()、onStart()、onResunme()三个方法

点击第一个按钮:

此时控制台:

由于secondActivity完全把firstActivity遮挡住

因此会执行onPause()方法和onStop()方法

点击Back键返回:

由于之前的firstActivity已经进入了停止状态

所以onRestart()方法会得到执行

之后一次执行onStart()和onResume()方法

此时的onCreate()方法不会执行

因为该活动没有重新创建

如果活动没有完全泽当当前的活动

只会执行onPause()方法

onStop()方法不会执行

此时的前一个活动只是进入了暂停状态

按Back返回

也只有onResume()方法被执行

若退出程序:

此时会一次执行以上的三个方法,最终销毁FirstActivity

1.4.5、活动被收回了怎么办?

当一个活动进入了停止状态是有可能被系统收回的

一个活动启动了零一活动,前一个活动被系统回收

再次返回到前一个活动会正常显示的

不同的是这里不会执行onRestart()方法

会执行onCreate(0方法进行重新创建活动

问题:

前一个活动中额能存在临时数据和状态

一旦返回到前一个活动会将之前的数据和状态都丢失掉

这会影响到用户的体验

Activity中提供了onSaveInstanceState()回调方法

这个方法可以保证活动在回调之前一定被调用

故可以使用这个方法进行解决回收之前数据得不到保存的问题

onSaveInstanceState()方法会携带一个参数Bundle类型的参数

Bundle提供了一系列的方法用户保存数据

如使用putString()方法来保存数据

putInt()方法来保存整形数据等

两个参数:

1、键,用于后面的Bundle取值

2、值,即是要保存的数据

在FirstActivity中:

    @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);String date = "保存的数据";outState.putString("date",date);}

这里的数据只是测试保存零时数据

实际开发中可能保存的是文本框中的值等

数据恢复:

 @Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout);if (savedInstanceState != null){String date = savedInstanceState.getString("date");Log.d("date====",date);}......}

这里的onCreate()方法中有一个Bundle类型的参数

一般情况下是null

如果在回收之前执行了上述的报保存数据的方法,这个参数就会保存之前所有保存过的临时数据

同理使用Bundle也可以进行数据的传送!!!

1.5、活动的启动模式

在实际的开发中需要指定每个活动的启动方式

启动模式一共有4中:

1、standard

2、singleTop

3、singleTask

4、singleInstance

可以在<activity>标签中指定android:launchMode来选择启动模式

1、standard

活动的默认启动 方式,在不进行显示的指定的情况下都会默认使用这个启动模式

每启动一个活动就会在返回栈中入栈且处于栈顶的位置

对于这种模式的活动,系统不会在乎这个活动是都已经在栈中存在,每次启动都会创建该活动的新实例

测试:

    @Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout); Log.d("FirstActivity====",this.toString());Button first = (Button) findViewById(R.id.button_first);first.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this,SecondActivity.class);startActivity(intent);}});}

这里使用上述的Log进行打印:

启动的时候进行的打印:

有三两个实例此时需要2次Back键才能退出程序

模式的原理示意图:

2、singleTop

在启动活动的时候如果发现返回栈顶已经是该活动,则认为可以直接使用它

不会再创建新的实例

在注册文件中

 <activityandroid:name=".FirstActivity" android:launchMode="singleTop"android:label="first"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

其余不变进行测试启动:

之后不管点击按钮多少次都不会再有新的打印信息

该活动已经处于栈顶

每当想要在启动一个FristActivity都会直接使用栈顶的活动,该混动也就是只有一个实例

仅按一次Back键即可退出程序

若FirstActivity未处于栈顶的位置时,在启动FirstActivity会创建新的实例

测试:

对于SecondActivity中:

  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second_activity);Button button = (Button) findViewById(R.id.button_return1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent  = new Intent(SecondActivity.this,FirstActivity.class);startActivity(intent);}});}

其余不变启动测试:

点击按钮之后再点击回退:

可以看到两个不同的FirstActivity实例

由于再SecondActivity中再次启动FirstActivity栈顶已经变成了SecondActivity

因此会创建一个新的实例

按back键就会返回到SecondActivity

再按一下back会返回到FisrstActivity

最后早按一下退出程序

原理示意图:

3、singleTask

每次启动活动时系统首先会在返回栈中检查是否存在过该活动的实例

如果发现则直接使用该实例并且把这个活动之上的所有活动统统出栈

如果没有则会创建一个新的活动实例

与SingleTop不同,后者是可以很好的解决重复出栈的问题,但是

该活动若没有处于栈顶的位置会创建多个活动的实例

FirstActivity

public class FirstActivity extends AppCompatActivity {@Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("FirstActivity====",this.toString());setContentView(R.layout.first_layout);Button first = (Button) findViewById(R.id.button_first);first.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this,SecondActivity.class);startActivity(intent);}});}@Overrideprotected void onRestart() {super.onRestart();Log.d("FirstActivity====",this.toString());}
}

注册文件中:

<activityandroid:name=".FirstActivity" android:launchMode="singleTask"android:label="first"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

SecondActivity.java
public class SecondActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second_activity);Button button = (Button) findViewById(R.id.button_return1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent  = new Intent(SecondActivity.this,FirstActivity.class);startActivity(intent);}});}@Overrideprotected void onDestroy() {super.onDestroy();Log.d("destory:", "活动2已经关闭");}
}

启动时:

点击事件出发返回后:

此时可以看见该栈之上的所有栈都被关闭

此时点击一次Back就可以退出程序

原理示意图:

4、singleInstance

指定该模式的活动会启用一个新的返回栈来管理这个活动

假设我们的程序中有一个活动是可以允许其他程序调用

想实现其他程序和我们的程序可以共享这个活动的实例

使用singleInstance模式可以解决这个问题

在这个模式下会有一个单独的返回栈来管理这个活动

不管是那个应用程序来访问这个活动都公用一个返回栈,这样解决了共享活动实例的问题

配置文件中对SecondActivity进行设置

        <activityandroid:name=".SecondActivity"android:launchMode="singleInstance"></activity>

对代码进行修改:

FirstActivity.java

  @Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);
        Log.d("FirstActivity====", String.valueOf(getTaskId()));setContentView(R.layout.first_layout);Button first = (Button) findViewById(R.id.button_first);first.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this,SecondActivity.class);startActivity(intent);}});}

SecondActivity.java

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second_activity);Log.d("SecondActivity====", String.valueOf(getTaskId()));Button button = (Button) findViewById(R.id.button_return1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent  = new Intent(SecondActivity.this,ThirdActivity.class);startActivity(intent);}});}

ThirdActivity.java

   @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.third_activity);  Log.d("ThirdActivity====", String.valueOf(getTaskId()));}

首先启动:

点击去SecondActivity

再点击去ThirdActivity

再back直接返回到FirstActivity

再Back直接返回到SecondActivity

再Back退出程序

这时候所有的栈都已经空了

示意图如下:

转载于:https://www.cnblogs.com/Mrchengs/p/10659278.html

1、Android-活动(下)相关推荐

  1. android没有输入焦点类控件的输入法调用,Android 手机下输入框获取焦点时, 输入法会挡住输入框...

    // Android 手机下输入框获取焦点时, 输入法会挡住输入框 // 解决方法: // Android 手机下, input 或 textarea 元素聚焦时, 主动滚动 if (/Android ...

  2. android实例化一个活动,Android活动 - 无法实例化活动组件信息

    我正在尝试编写一个程序,该程序在单击下一个按钮时显示一个字符串"hello". 我已经采取了两项活动.当我运行我得到这个日志猫.我是新的android编程请帮助我.Android活 ...

  3. android有多个活动,Android活动一探究竟

    作为Android的四大组件之一,活动最先走进我们的视野,其重要性不言而喻,今天就抽出时间来专门对Android活动一探究竟. 什么是活动 活动即Activity,是一种可以包含用户界面的组件,And ...

  4. 《Android应用开发攻略》——1.15 程序:Android OS下的小费计算器Tipster

    1.15 程序:Android OS下的小费计算器Tipster Sunit Katkar 1.15.1 问题 当你和朋友前往饭店就餐并且希望计算各自的账单和小费时,可能陷入许多手动计算和分歧之中.你 ...

  5. 基于Android环境下象棋的设计程序,基于Android平台的中国象棋设计与实现

    摘要: 近年,随着第三代数字通信技术的发展,数字信息产品如手机,IPad,PDA等开始获得用户的广泛接受和良好的体验.作为移动终端设备的数字信息产品己经从仅仅将通信作为唯一目标的模式演变成了具有更多市 ...

  6. android finish 不起作用,在Android活动上调用finish()实际上并没有完成

    在Android活动上调用finish()实际上并没有完成 我打了finish(),但我的活动仍在继续. 我有一个活动,该活动由主活动屏幕上的菜单调用. 在我的活动的finish()方法中,我具有以下 ...

  7. 删除android软件,adb shell删除Android系统下的软件

    一.删除Android系统下的软件,使用adb shell进入系统,然后使用命令重新挂载"/system"目录为读写权限,具体操作及命令如下: 1.打开dos窗口:win+R 输入 ...

  8. Android Studio下的目录结构

    我们可以看一下Android Studio下的目录结构. 在Android Studio的左上角,可以切换不同的视图, 选择Android视图,可以查看Android Studio的工程目录结构,如下 ...

  9. Android studio 下 JNI 开发实例

    在AS中进行 NDK 开发之前,我们先来简单的介绍几个大家都容易搞懵的概念: 到底什么是JNI,什么是NDK? 何为"交叉编译"? 先看什么是 JNI?JNI 的全称就是 Java ...

  10. ubuntu 运行android sdk 下的工具adb报bash: ./adb: No such file or directory

    ubuntu 运行android sdk 下的工具adb报bash: ./adb: No such file or directory 运行adb出现这种错误: bash: ./adb: No suc ...

最新文章

  1. CentOS下安装Telnet
  2. 文件加载顺序_Springboot配置文件存放位置及读取顺序
  3. 电容式传感器位移性能试验报告_圆柱形电容式接近开关可以分3类?
  4. [转载] 晓说——第9期:多如牛毛严酷无比的美国那些法
  5. 增量更新同步_OneDrive增量更新功能正式推出 仅同步文件更改部分降低网络占用...
  6. .Net中json序列化与反序列化
  7. param参数服务器
  8. 修改一个CGRect的值
  9. 查询成绩最好的前两名_SQL查询整理
  10. JQuery与springmvc实现单个文件上传操作
  11. java命令_java常用命令javac、javap、jps、jstack
  12. 联想硬盘保护系统密码读取
  13. 海康录像机能用别的摄像头吗_海康威视录像机如何添加大华摄像头
  14. 全票通过!数据集成平台 SeaTunnel 成功进入 Apache 孵化器!
  15. Audio-PCM设备的创建
  16. 当C++遇上AUTOSAR编码规范,你的安全我来护航
  17. NOIP2018赛前停课集训记(10.24~11.08)
  18. 微信小程序开发05 研发加速:使用 Webpack 提升小程序研发效率
  19. mysql5.7.19winx64安装_mysql5.7.19winx64安装配置方法图文教程(win10)
  20. vue为什么需要nodejs 的环境

热门文章

  1. [转载] 为什么this()和super()必须是构造函数中的第一条语句?
  2. [转载] Java——System.exit()用法及个人理解
  3. ByteToByte64String、Base64StringToBytes
  4. C# AE 对图层筛选要素后显示/只显示符合条件的要素
  5. 将公司的主要项目从eclipse迁移到android studio for mac环境(1)
  6. Struts1.x多文件上传问题
  7. VScode+远程服务器docker+C/C++ 代码挑战配置
  8. 【RobotStudio学习笔记】(八)速度设置
  9. 正则化regularization
  10. 黑群晖 linux 修改参数,黑群晖 DS918+ 修改引导参数隐藏引导盘和数据盘