Android应用开发:Activity(3)

目录

6、Activity 的生命周期

(1)返回栈

(2) Activity 状态

(3) Activity 的生存期

(4)体验 Activity 的生命周期

(5)Activity 被回收了怎么办


6、Activity 的生命周期

(1)返回栈

        Android 是使用任务(task来管理 Activity 的,一个任务就是一组存放在栈里的 Activity 的集合,这个栈也被称作返回栈

        栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个Activity时,处于栈顶的Activity就会出栈,前一个入栈的Activity就会重新处于栈顶的位置。

        系统总是会显示处于栈顶的Activity给用户。

(2) Activity 状态

每个 Activity 在其生命周期中最多可能会有四种状态。

① 运行状态

        但一个 Activity 位于返回栈的栈顶时,Activity 就处于运行状态。系统最不愿意回收的就是处于运行状态的 Activity,因为这会带来非常差的用户体验。

② 暂停状态

        当一个 Activity 不再处于栈顶位置,但仍然可见,Activity 就进入了暂停状态(比如对话框形式的 Activity 只会占用屏幕中间的部分区域),处于暂停状态的 Activity 是完全存活着的。

③ 停止状态

        当一个 Activity不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态,有可能会被系统回收。

④ 销毁状态

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

(3) Activity 的生存期

Activity 类中定义了7个回调方法,覆盖了 Activity 生命周期的每一个环节。

• onCreate() 这个方法在Activity第一次被创建的时候调用。

 onStart() 这个方法在Activity由不可见变为可见的时候调用。

• onResume() 这个方法在Activity准备好和用户进行交互的时候调用。

• onPause() 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。

onStop() 这个方法在Activity完全不可见的时候调用。

onDestroy() 这个方法在Activity被销毁之前调用。

• onRestart() 这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

(4)体验 Activity 的生命周期

① 新建一个 ActivityLifeCycleTest 项目

② 再创建两个子 Activity:NormalActivity 和 DialogActivity

布局命名为 normal_layout 和 dialog_layout

③ 编辑normal_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NormalActivity">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is a normal activity"/>

</LinearLayout>

④ 编辑 dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DialogActivity">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is a dialog activity"/>

</LinearLayout>

⑤ 修改 AndroidManifest.xml 的<activity> 标签的配置

        android:theme 属性,用于给当前 Activity 指定主题,Android 系统内置很多主题可以选择,当然也可以自己定制主题。

<activity
            android:name=".DialogActivity"
            android:theme="@style/Theme.AppCompat.Dialog"
            android:exported="false" />

⑥ 修改 activity_main.xml,重新定制主 Activity 的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/startNormalActivity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start NormalActivity"/>

    <Button
        android:id="@+id/startDialogActivity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start DialogActivity"/>

</LinearLayout>

⑦ 最后修改MainActivity 中的代码

class MainActivity : AppCompatActivity() {

    private val tag = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(tag,"onCreate")
        setContentView(R.layout.activity_main)

        startNormalActivity.setOnClickListener { 
            val intent = Intent(this,NormalActivity::class.java)
            startActivity(intent)
        }
        
        startDialogActivity.setOnClickListener {
            val intent = Intent(this,DialogActivity::class.java)
            startActivity(intent)
        }
        
    }

    override fun onStart() {
        super.onStart()
        Log.d(tag,"onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d(tag,"onResume")
    }

    override fun onPause() {
        super.onPause()
        Log.d(tag,"onPause")
    }

    override fun onStop() {
        super.onStop()
        Log.d(tag,"onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(tag,"onDestroy")
    }

    override fun onRestart() {
        super.onRestart()
        Log.d(tag,"onRestart")
    }
}

⑧ 运行程序,观察 Logcat 中的打印日志

点击第一个按钮

按下Back键

按第二个按钮

        只有 onPause( ) 方法得到了执行,onStop( ) 方法并没有执行,这是因为 DialogActivity 并没有完全遮挡注 MainActivity,此时 MainActivity 只是进入了暂停状态,并没有进入停止状态。

按下Back键也只有 onResume( )方法会得到执行

最后按下 Back 键退出程序

(5)Activity 被回收了怎么办

        当一个 Activity 进入停止状态,是可能会被系统回收的。按Back 返回可能会出现前一个 Activity 临时数据被回收的情况

        Activity 中提供了一个 onSaveInstanceState( ) 回调方法,可以保证在 Activity 被回收之前一定会被调用。onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用 putString())方法保存字符串,使用 putInt()方法保存整型数据,以此类推。每个保存方法需要传人两个参数,第一个参数是键,用于后面从Bundle中取值,第二个参数是真正要保存的内容。

在MainActivity中添加如下代码就可以将临时数据进行保存了:

override fun onSaveInstanceState(outState: Bundle){
	super.onSaveInstanceState(outState)
	val tempData ="Something you just typed"
	outState.putString("data key",tempData)
}

        我们一直使用的 onCreate()方法其实也有一个 Bundle 类型的参数。这个参数在一般情况下都是null.但是如果在 Activity 被系统回收之前,你通过 onSaveInstanceState()方法保存数据,这个参数就会带有之前保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可

修改 MainActivity的onCreate()方法,如下所示:

override fun onCreate(savedInstanceState: Bundle?){
	super.onCreate(savedInstanceState) 
    Log.d(tag,"onCreate")
	setContentView(R.layout.activity_main) 
    if (savedInstanceState != null){
		val tempData =savedInstanceState.getString("data_key") 
        Log.d(tag,tempData)
    }
    ...
}

        取出值之后再做相应的恢复操作就可以了,比如将文本内容重新赋值到文本输入框上,这里我们只是简单地打印一下。

        Intent还可以结合Bundle一起用于传递数据。首先我们可以把需要传递的数据都保存在 Bundle 对象中,然后再将Bundle对象存放在 Intent里。到了目标 Activity 之后,先从 intent 中取出 Bundle,再从 Bundle 中一一取出数据。

        另外,当手机的屏幕发生旋转的时候,Activity也会经历一个重新创建的过程,因而在这种情况下,Activity中的数据也会丢失。虽然这个问题同样可以通过 onSaveInstanceState()方法来解决,但是一般不太建议这么做。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值