Android5:活动生命周期
创建项目Stopwatch
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns: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"><Chronometerandroid:id="@+id/stopwatch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="56sp" /><Buttonandroid:id="@+id/start_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/start" /><Buttonandroid:id="@+id/pause_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/pause" /><Buttonandroid: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.stopwatchimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.widget.Button
import android.widget.Chronometerclass MainActivity : AppCompatActivity() {lateinit var stopwatch: Chronometer //The stopwatchvar running = false //Is the stopwatch running?var offset: Long = 0 //The base offset for the stopwatchoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//Get a reference to the stopwatchstopwatch = findViewById<Chronometer>(R.id.stopwatch)//The start button starts the stopwatch if it's not runningval 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 runningval 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 0val resetButton = findViewById<Button>(R.id.reset_button)resetButton.setOnClickListener {offset = 0setBaseTime()}}//Update the stopwatch base time, allowing for any offsetfun setBaseTime() {stopwatch.base = SystemClock.elapsedRealtime() - offset}//Record the offsetfun saveOffset() {offset = SystemClock.elapsedRealtime() - stopwatch.base}
}
运行查看效果
代码说明
1.应用运行,MainActivity
启动
初始化running
和offset
属性
2.调用MainActivity
的onCreate
方法
将activity_main.xml
布局链接到活动,为stopwatch
属性指定视图的一个引用
3.点击“Start”按键
秒表开始运行
4.点击“Pause”按钮
更新offset
属性,并调用秒表的stop
方法,running
更新为false
,秒表暂停
5.再次点击“Start”按钮
使用offset
的值来调整stopwatch.base
属性,调用start
方法,更新running
为true
,表秒再次运行
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.stopwatchimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.widget.Button
import android.widget.Chronometerclass MainActivity : AppCompatActivity() {lateinit var stopwatch: Chronometer //The stopwatchvar running = false //Is the stopwatch running?var offset: Long = 0 //The base offset for the stopwatch//Add key Strings for use with the Bundleval 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 stopwatchstopwatch = findViewById<Chronometer>(R.id.stopwatch)//Restore the previous stateif (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 runningval 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 runningval 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 0val resetButton = findViewById<Button>(R.id.reset_button)resetButton.setOnClickListener {offset = 0setBaseTime()}}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 offsetfun setBaseTime() {stopwatch.base = SystemClock.elapsedRealtime() - offset}//Record the offsetfun saveOffset() {offset = SystemClock.elapsedRealtime() - stopwatch.base}
}
相关文章:

Android5:活动生命周期
创建项目Stopwatch activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_w…...
第2章 数据结构和算法概述
2.3线性结构和非线性结构 数据结构包括: 线性结构和非线性结构 2.3.1线性结构 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系线性结构有两种不同的存储结构,即顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称…...

WPF国际化的实现方法(WpfExtensions.Xaml)
https://blog.csdn.net/eyupaopao/article/details/120090431 resx资源文件实现 resx资源文件,实现的过程比第一种复杂,但resx文件本身编辑比较简单,维护起来比较方便。需要用到的框架:WpfExtensions.Xaml 为每种语言添加.resx资…...

【Linux】—— 进程程序替换
目录 序言 (一)替换原理 1、进程角度——见见猪跑 1️⃣ 认识 execl 函数 2、程序角度——看图理解 (二)替换函数 1、命名理解 2、函数理解 1️⃣execlp 2️⃣execv 3️⃣execvp 4️⃣execle 5️⃣execve 6️⃣execve…...

idea创建javaweb项目,jboss下没有web application
看看下图这个地方有没有web application...

广东灯具3D扫描抄数建模服务3D测绘出图纸三维逆向设计-CASAIM
灯具三维逆向建模是一种将实际物体转换为数字模型的过程。通过逆向工程技术,可以将现有的灯具进行3D扫描,然后利用专业的逆向设计软件将其转换为准确的三维模型。 以下是CASAIM实施灯具三维逆向建模的一般步骤图: 1. 扫描:三维扫…...
Nginx反向代理-负载均衡、webshell实践
目录 1.nginx反向代理-负载均衡 1)搭建web项目 2)修改 nginx.conf的配置 2.webshell 实践 1)异或操作绕过 2)取反绕过 3)php语法绕过 1.nginx反向代理-负载均衡 1)搭建web项目 首先通过SpringBoo…...

第六阶|见道明心的笔墨(上)从书法之美到生活之美——林曦老师的线上直播书法课
如果你有需要,可以找我的,我这边有老师的所有课程 如果你有需要,可以找我的,我这边有老师的所有课程...
nbcio-boot从3.0升级到3.1的出现用户管理与数据字典bug
升级后出现 系统管理里的用户管理出现下面问题 2023-08-17 09:44:38.902 [http-nio-8080-exec-4] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - java.lang.String cannot be cast to java.lang.Long java.lang.ClassCastException:…...

Curson 编辑器
Curson 汉化与vacode一样 Curson 自带chat功能 1、快捷键ctrlk(代码中编辑) 2、快捷键ctrll 右侧打开窗口...
Shell编程学习之函数的应用
Shell编程中的函数:伪代码表示: function 函数名(){函数体}注意事项: 1.函数无参数; 2.函数无返回值类型; 3.function可以不写; 4.函数不被调用,就不会执行; 5.函数名不能使用…...

Fork/Join框架
是什么 Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 Fork: 把一个大任务切分为若干子任务并行的执行 Join: 合并这些子任务的执行结果,最后…...
LeetCode_字符串_中等_468.验证 IP 地址
目录 1.题目2.思路3.代码实现(Java) 1.题目 给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 “IPv4” ;如果是有效的 IPv6 地址,返回 “IPv6” ;如果不是上述类型的 IP 地址,返回 “Nei…...

ABAP Der Open SQL command is too big.
ABAP Der Open SQL command is too big. DBSQL_STMNT_TOO_LARGE CX_SY_OPEN_SQL_DB 应该是选择条件中 维护的条件值条数太多了...

QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis)
QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis) 1、数据序列类 继承关系 2、坐标轴类 的继承关系 3、图例类 什么是图例? 图例:是集中于地图…...
Servlet+JDBC实战开发书店项目讲解第10篇:在线客服功能实现
在线客服功能实现 实现思路 要实现在线客服功能,您可以考虑以下步骤: 创建一个用于存储客户消息和回复的数据库表。您可以使用JDBC连接到数据库,并使用SQL语句创建表格。 在您的Servlet中,创建一个用于处理客户消息和回复的POS…...

CVE-2023-21292 AMS框架层高危漏洞分析
文章目录 前言漏洞细节故事起源漏洞利用漏洞修复 总结 前言 本周在分析 Google 官方发布的 Android 2023 年8 月安全公告 涉及的漏洞补丁的时候,遇到一个有意思的漏洞:CVE-2023-21292。 之所以说它有意思是因为这个漏洞早在去年年底就在某平台上被国外…...
cuda、cuDNN、深度学习框架、pytorch、tentsorflow、keras这些概念之间的关系
当讨论CUDA、cuDNN、深度学习框架、pytorch、tensorflow、keras这些概念的时候,我们讨论的是与GPU加速深度学习相关的技术和工具。 CUDA(Compute Unified Device Architecture): CUDA是由NVIDIA开发的一种并行计算平台和编程模型&…...

第二讲:BeanFactory的实现
BeanFactory的实现 1. 环境准备2. 初始化DefaultListableBeanFactory3. 手动注册BeanDefinition4. 手动添加后置处理器5. 获取被依赖注入的Bean对象6. 让所有的单例bean初始化时加载7. 总结 Spring 的发展历史较为悠久,因此很多资料还在讲解它较旧的实现,…...

vue2+Spring Boot2.7 大文件分片上传
之前我们文章 手把手带大家实现 vue2Spring Boot2.7 文件上传功能 将了上传文件 但如果文件很大 就不太好处理了 按正常情况甚至因为超量而报错 这里 我弄了个足够大的文件 我们先搭建 Spring Boot2.7 环境 首先 application.yml 代码编写如下 server:port: 80 upload:path:…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...