Android5:活动生命周期

创建项目Stopwatch


activity_main.xml




    

    

strings.xml


    Stopwatch
    Start
    Pause
    Reset

MainActivity.kt

package com.demo.stopwatch

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.widget.Button
import android.widget.Chronometer

class MainActivity : AppCompatActivity() {

    lateinit var stopwatch: Chronometer  //The stopwatch
    var running = false  //Is the stopwatch running?
    var offset: Long = 0  //The base offset for the stopwatch

    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Get a reference to the stopwatch
        stopwatch = findViewById(R.id.stopwatch)

        //The start button starts the stopwatch if it's not running
        val startButton = findViewById

运行查看效果

代码说明
1.应用运行,MainActivity启动
初始化runningoffset属性
2.调用MainActivityonCreate方法
activity_main.xml布局链接到活动,为stopwatch属性指定视图的一个引用
3.点击“Start”按键
秒表开始运行
4.点击“Pause”按钮
更新offset属性,并调用秒表的stop方法,running更新为false,秒表暂停
5.再次点击“Start”按钮
使用offset的值来调整stopwatch.base属性,调用start方法,更新runningtrue,表秒再次运行
6.点击“Reset”按钮
offset更新为0,stopwatch.base属性更新为SystemClock.elapsedRealtime()

但是这里有个问题,当旋转屏幕时,秒表会重置为0,并停止运行
Android5:活动生命周期_第1张图片

旋转时发生了什么?
当屏幕方向有变化时,Android会撤销MainActivity,所以MainActivity的属性值会丢失
然后MainActivity会重启,它的所有属性都会重新初始化,并且再次运行onCreate()方法

活动从启动状态变成撤销状态时,会触发一些活动生命周期的方法:onCreate()onDestroy()。这些是活动继承的生命周期方法,不过可以覆盖这些方法。

解决方案:使用Bundle

Bundle是一种保存键值对的对象。在活动撤销之前,Android允许你把键值对放在Bundle里面,然后在活动重建时,活动的新实例通过Bundle恢复属性值

活动撤销前都会调用onSaveInstanceState方法,所以这里需要覆盖onSaveInstanceState方法

活动重建时会调用onCreate()方法,这里通过检查savedInstanceState != null来判断是否需要恢复属性值

MainActivity.kt最终代码

package com.demo.stopwatch

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.widget.Button
import android.widget.Chronometer

class MainActivity : AppCompatActivity() {

    lateinit var stopwatch: Chronometer  //The stopwatch
    var running = false  //Is the stopwatch running?
    var offset: Long = 0  //The base offset for the stopwatch

    //Add key Strings for use with the Bundle
    val OFFSET_KEY = "offset"
    val RUNNING_KEY = "running"
    val BASE_KEY = "base"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Get a reference to the stopwatch
        stopwatch = findViewById(R.id.stopwatch)

        //Restore the previous state
        if (savedInstanceState != null) {
            offset = savedInstanceState.getLong(OFFSET_KEY)
            running = savedInstanceState.getBoolean(RUNNING_KEY)
            if (running) {
                stopwatch.base = savedInstanceState.getLong(BASE_KEY)
                stopwatch.start()
            } else setBaseTime()
        }

        //The start button starts the stopwatch if it's not running
        val startButton = findViewById

你可能感兴趣的:(Android,android)