Android5:活动生命周期

news2024/12/23 12:47:12

创建项目Stopwatch

在这里插入图片描述
activity_main.xml

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

    <Chronometer
            android:id="@+id/stopwatch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="56sp" />

    <Button
            android:id="@+id/start_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/start" />

    <Button
            android:id="@+id/pause_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/pause" />

    <Button
            android:id="@+id/reset_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/reset" />
</LinearLayout>

strings.xml

<resources>
    <string name="app_name">Stopwatch</string>
    <string name="start">Start</string>
    <string name="pause">Pause</string>
    <string name="reset">Reset</string>
</resources>

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<Chronometer>(R.id.stopwatch)

        //The start button starts the stopwatch if it's not running
        val startButton = findViewById<Button>(R.id.start_button)
        startButton.setOnClickListener {
            if (!running) {
                setBaseTime()
                stopwatch.start()
                running = true
            }
        }

        //The pause button pauses the stopwatch if it’s running
        val pauseButton = findViewById<Button>(R.id.pause_button)
        pauseButton.setOnClickListener {
            if (running) {
                saveOffset()
                stopwatch.stop()
                running = false
            }
        }

        //The reset button sets the offset and stopwatch to 0
        val resetButton = findViewById<Button>(R.id.reset_button)
        resetButton.setOnClickListener {
            offset = 0
            setBaseTime()
        }
    }
    

    //Update the stopwatch base time, allowing for any offset
    fun setBaseTime() {
        stopwatch.base = SystemClock.elapsedRealtime() - offset
    }

    //Record the offset
    fun saveOffset() {
        offset = SystemClock.elapsedRealtime() - stopwatch.base
    }
}

运行查看效果

代码说明
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,并停止运行
在这里插入图片描述

旋转时发生了什么?
当屏幕方向有变化时,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<Chronometer>(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<Button>(R.id.start_button)
        startButton.setOnClickListener {
            if (!running) {
                setBaseTime()
                stopwatch.start()
                running = true
            }
        }

        //The pause button pauses the stopwatch if it’s running
        val pauseButton = findViewById<Button>(R.id.pause_button)
        pauseButton.setOnClickListener {
            if (running) {
                saveOffset()
                stopwatch.stop()
                running = false
            }
        }

        //The reset button sets the offset and stopwatch to 0
        val resetButton = findViewById<Button>(R.id.reset_button)
        resetButton.setOnClickListener {
            offset = 0
            setBaseTime()
        }
    }

    override fun onPause() {
        super.onPause()
        if (running) {
            saveOffset()
            stopwatch.stop()
        }
    }

    override fun onResume() {
        super.onResume()
        if (running) {
            setBaseTime()
            stopwatch.start()
            offset = 0
        }
    }

    override fun onSaveInstanceState(savedInstanceState: Bundle) {
        savedInstanceState.putLong(OFFSET_KEY, offset)
        savedInstanceState.putBoolean(RUNNING_KEY, running)
        savedInstanceState.putLong(BASE_KEY, stopwatch.base)
        super.onSaveInstanceState(savedInstanceState)
    }

    //Update the stopwatch base time, allowing for any offset
    fun setBaseTime() {
        stopwatch.base = SystemClock.elapsedRealtime() - offset
    }

    //Record the offset
    fun saveOffset() {
        offset = SystemClock.elapsedRealtime() - stopwatch.base
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/899399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

产品经理必知必会0.2

Q1:产品经理需要具备的能力&#xff1f; A:硬实力&#xff1a;产品设计、需求分析、竞品分析、数据分析、撰写文档 软实力&#xff1a;沟通能力、学习能力、用户思维、主动性、好奇心、同理心、责任心、抗压能力、目标导向.... 扩展能力&#xff1a;商业思维、市场敏感度... Q…

3D与沉浸式技术,如何助力企业数字化转型?

说起3D&#xff0c;估计许多读者朋友会在第一时间想起《阿凡达》系列和《侏罗纪公园》系列电影大作。每一帧细节纤毫毕现的逼真画面&#xff0c;让观众几乎分不清虚拟与现实&#xff0c;完全沉浸在导演打造的视觉盛宴中。 事实上&#xff0c;除了大家所熟知的3D影视动画之外&am…

ps丢失d3dcompiler_47.dll怎么办,启动无反应,分享三个解决方法

d3dcompiler_47.dll64位是windows系统中重要的dll文件&#xff0c;缺少了它可能会引起部分软件或者游戏不能运行。 如果系统出现“找不到d3dcompiler_47.dll”或“d3dcompiler_47.dll丢失”等错误信息&#xff0c;那么我们就该着手修复它。 先带了解一下d3dcompiler_47.dll是什…

【MATLAB基础绘图第16棒】绘制热图(Heatmap)

热图&#xff08;Heatmap&#xff09; 热图的主要作用是直观展示重点研究对象的差异情况&#xff0c;多用于经济学与工学差异性分析之中。 heatmap函数创建热图 语法 hheatmap(tbl,xvar,yvar) hheatmap(tbl,xvar,yvar,ColorVariable,cvar) hheatmap(cdata) hheatmap(xvalue…

开发板启动过程

开发板启动过程 开发板上电后首先运行SOC内部iROM中固化的代码(BL0)&#xff0c;这段代码先对基本的软硬件环境(时钟等…)进行初始化&#xff0c;然后再检测拨码开关位置获取启动方式&#xff0c;然后再将对应存储器中的uboot搬移到内存&#xff0c;然后跳转到uboot运行 uboot…

《TCP IP网络编程》第二十四章

第 24 章 制作 HTTP 服务器端 24.1 HTTP 概要 本章将编写 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;服务器端&#xff0c;即 Web 服务器端。 理解 Web 服务器端&#xff1a; web服务器端就是要基于 HTTP 协议&#xff0c;将网页对…

将挖洞当作爱好和职业的笑与泪:微软漏洞研究员的自白

前言 本文主人公目前是微软的一名漏洞研究员&#xff0c;他讲述了将挖洞当作爱好和当作职业的笑与泪&#xff0c;以及一些建议忠告。 我写的通常都是自己挖到的有意思的浏览器 bug&#xff0c;希望能借读者一臂之力&#xff0c;应用这些经验或思路。不过这次我写的是将挖洞作…

kicad 7 如何设置画直线

kicad 7和之前的版本有些地方不一样&#xff0c;有些默认的快捷键失效了&#xff0c;比如画直线的功能。小伙伴们可以按照下图操作&#xff0c;点击该按钮&#xff0c;画出的线就是直直的线了~ 图1&#xff1a;Kicad 7 画直线的按钮 作者&#xff1a;潇洒的电磁波&#xff08;…

妙鸭爆火给AI开发者的启示;最全LangChain资源库;LLM大学;大模型实践长文总结 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; AI全流程动画「剪刀石头布2」&#xff0c;以及幕后制作解析 BV1oV41137Vr BV1SG411Z77M 油管知名博主 Corridor Crew 用AI工具 Stable…

8.1.5:Extreme Optimization Numerical Libraries for .NET

构建金融、工程和科学应用程序。 Extreme Optimization Numerical Libraries for .NET 是通用数学和统计类的集合。它为基于 Microsoft .NET 平台构建的技术和统计计算提供了一个完整的平台。它将数学库、向量和矩阵库以及统计库结合在一个方便的包中。 一般特征 即使对数学不太…

掌握信息,事半功倍!高效搜索引擎采集软件助您引领信息时代

掌握信息&#xff0c;事半功倍&#xff01;高效搜索引擎采集软件助您引领信息时代&#xff01; 您是否曾为了查找相关数据而浪费大量时间和精力&#xff1f;您是否渴望一款高效、便捷的软件来帮助您从海量信息中快速提取所需&#xff1f;现在&#xff0c;我们为您呈现一款全新…

SAP ABAP SQL查询语句-内连接与左连接使用

SQL查询语句-内连接与左连接使用 程序: data:begin of itab OCCURS 0,material type /bic/oizmaterial,batch type /bi0/oibatch,brd type /bic/oizzbrd,cpquabu type /bi0/oicpquabu,end of itab. *&**例一: clear: itab[]. select * into corresponding fields…

【C语言】字符函数和字符串函数

目录 1.求字符串长度strlen 2.长度不受限制的字符串函数 字符串拷贝strcpy 字符串追加strcat 字符串比较strcmp 3.长度受限制的字符串函数介绍strncpy strncat ​编辑strncmp 4.字符串查找strstr 5.字符串分割strtok 6.错误信息报告 strerror perror 7.字符分类函…

logstash配置文件

input { kafka { topics > “xxxx” bootstrap_servers > “ip:port” auto_offset_reset > “xxxx” group_id > “xxxx” consumer_threads > 3 codec > “json” } } filter { grok { match > { “message” > ‘%{IP:client_ip} - - [%{HTTPDATE:…

机器学习深度学习——BERT(来自transformer的双向编码器表示)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——transformer&#xff08;机器翻译的再实现&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&am…

2023最新版本~KEIL5使用C++开发STM32

先看效果 开始教学 因为是第一次写这个配置教程 我会尽量详细些 打开一个Keil工程 移除本地core 添加在线core 第一次编译代码 不会有报错 修改main.c文件类型为C 点击魔术棒 把ARM编译器修改为V6 第二次编译会报错语法不兼容 我把汇编部分的这些代码做了…

CSGO游戏搬砖项目为什么这么火,还能做多久?

不得不说&#xff0c;现在的游戏饰品市场真的太疯狂了&#xff0c;越来越多的人带资入场。不管你会不会打游戏&#xff0c;不管你认不认可这个项目&#xff0c;事实就摆在这里。 还记得90年代香港股市的鱼翅捞饭时代吗&#xff1f;仿佛遍地都是黄金&#xff0c;只要弯腰就能捡…

Autosar存储入门系列01_NVM基础

本文框架 0.前言1. NVM基本概念1.1 基本概念及架构1.2 内置模拟EEPROM介绍1.3 外挂EPROM介绍 2.Sector/Page/Block相关概念2.1 Sector概念2.2 Page概念2.3 Block概念 总结 0.前言 最近工作比较忙&#xff0c;下班到家都快十点了&#xff0c;实在是没有多余的精力输出&#xff…

esp32c3 micropython oled实时天气信息

目录 简介 效果展示 代码 main.py ssd1306.py font.py 实现思路 简介 合宙esp32c3 micropython框架&#xff0c;只支持128*64 I2C oled ssd1306驱动我优化过的&#xff0c;与其他的不一样&#xff0c;为避免出错&#xff0c;使用我的驱动 把下面两个py文件放入单片机内…

什么是单例模式

什么是单例模式 文章目录 什么是单例模式1. 单例(单个的实例)2. 单例模式应用实例3. 饿汉式 VS 懒汉式 1. 单例(单个的实例) 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一…