当前位置: 首页 > news >正文

使用Handler创建一个Android秒表应用

本文所有代码都放在以下链接中:https://github.com/MADMAX110/Stopwatch

0、应用是一个有活动、布局和其他资源组成的集合。其中一个活动是应用的主活动。每个应用都有一个主活动,在文件AndroidManifest.xml中指定。
1、默认地,每个应用都在自己的进程中运行。这样有助于保证应用安全。
2、但是可以使用startActivity(intent)传入一个意图启动另一个应用中的活动。(Android系统知道设备上已安装的所有应用和它们的活动,可以使用意图启动适当的活动)。
3、需要启动一个活动时,Android会检查是否已经有一个进程在运行这个应用。(如果存在这样一个进程,Android就会在该进程中运行这个活动。如果不存在这样的进程,Android将创建一个进程)。
4、Android启动一个活动时,回调用它的onCreate()方法。(只要创建活动就会运行onCreate())。

下面通过来实现一个秒表应用,分析一下底层活动是如何工作的,应用通常会出什么问题,以及如何使用活动生命周期方法修正这些问题。秒表应用包括一个活动和一个布局。布局中有一个文本视图,显示已经过去了多少时间,另外还会显示一个Start(开始)按钮来启动秒表,一个Stop(停止)按钮停止秒表,还有一个Reset(重置)按钮可以将计时器重置为0。

创建新Android工程,应用名为Stopwatch,选择最低的SDK,如下图所示。
另外还需要一个名为StopwatchActivity的空活动和一个activity_stopwatch的布局。
在这里插入图片描述
工程目录如图所示:
在这里插入图片描述
更新strings.xml,添加以下三行代码:

    <string name="start">Start</string><string name="stop">Stop</string><string name="reset">Reset</string>

更新秒表布局代码
下面是布局的XML,这里描述了一个用来显示计时器的文本视图,另外还有三个按钮。
activity_stopwatch.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:padding="16dp"tools:context=".StopwatchActivity"><TextViewandroid:id="@+id/time_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textAppearance="@android:style/TextAppearance.Large"android:textSize="56sp"/><Buttonandroid:id="@+id/start_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:onClick="onClickStart"android:text="@string/start"/><Buttonandroid:id="@+id/stop_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="8dp"android:onClick="onClickStop"android:text="@string/stop"/><Buttonandroid:id="@+id/reset_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="8dp"android:onClick="onClickReset"android:text="@string/reset"/>
</LinearLayout>

单击Start按钮时会调用onCLickStop方法,单击Reset按钮时会调用onClickReset方法,单击Stop按钮时会调用onCLickStop方法。
我们还将使用一个名为runTimer()方法更新秒表。runTimer()方法每秒运行一次代码,检查秒表是否还在运行,如果确实还在运行,则使秒数递增,并在文本视图中显示秒数。
我们将使用两个私有变量记录秒表的状态。这里使用一个名为seconds的int变量跟踪秒表开始运行以来过去了多少秒,另一个使用一个名为running的布尔变量记录秒表目前是否还在运行。
为此,将StopwatchActivity.java的内容替换为以下代码:

package com.hfad.stopwatch;import android.app.Activity;
import android.os.Bundle;
import android.view.View;public class StopwatchActivity extends Activity {private int seconds = 0;//记录已经过去的秒数private boolean running;//秒表是否正常运行@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_stopwatch);}//启动秒表public void onClickStart(View view) {running = true;}//停止秒表public void onClickStop(View view) {running = false;}//单击reset按钮时会调用这个方法public void onClickReset(View view) {running = false;seconds = 0;}
}

创建runTimer方法,runTimer方法要得到布局中文视图引用,将seconds变量的内容格式化为小时,分钟和秒,然后在文本视图中显示。如果running变量设置为true,能让seconds变量递增。

private void runTimer() {//得到文本视图final TextView timeView = (TextView) findViewById(R.id.time_view);int hours = seconds / 3600;int minutes = (seconds%3600)/60;int secs = seconds % 60;//设置显示格式String time = String.format(Locale.getDefault(), "%d:%02d%02d", hours, minutes, secs);//设置文本视图timeView.setText(time);if (running) {++seconds;}}

要让这个代码一直循环,每秒递增seconds变量,并更新文本视图。而且要以一种不阻塞Android主线程的方式来实现。在非Android的Java程序中,可以使用后天线程完成类似这样的任务。不过在Android世界里,只有Android主线程可以更新用户界面,如果其他线程试图这样做,就会得到一个异常。可以使用Handler来解决这个问题。
Handler(消息处理器)是一个Android类,可以用来调度要在将来某个时间点运行的代码,还可以用它来提交需要在其他线程(非Android主线程)中运行的代码,在这里我们需要使用Handler调度秒表代码,让它每秒运行一次。
使用Handler时,可以把你想要调度的代码包装在一个Runnable对象中,然后使用Handler post()和postDelayed()方法指定希望这个代码在什么时间运行。
post()方法提交的代码要尽可能快地运行(通常几乎是立即运行),post()方法有一个参数,这是一个类型为Runnable的对象。Android世界里的Runable对象与普通Java中的Runnable很类似,就是你想要运行的一个作业。可以把想要运行的代码放在Runable的run()方法,Handler会确保这个代码尽可能快地运行。下面给出这个方法:

final Handler handler = new Handler();
handler.post(Runable);

postDelayed()方法与post()方法类似,只不过这个方法用来提交要在将来运行地代码。下面给出这个方法。

final Handler handler = new Handler();
handler.postDelayed(Runnable, long);

下面给出完整的StopwatchActivity代码:

package com.hfad.stopwatch;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Locale;
import android.os.Handler;public class StopwatchActivity extends Activity {private int seconds = 0;//记录已经过去的秒数private boolean running;//秒表是否正常运行@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_stopwatch);runTimer();//使用单独的方法更新秒表。创建活动会调用这个方法}//启动秒表public void onClickStart(View view) {running = true;}//停止秒表public void onClickStop(View view) {running = false;}//单击reset按钮时会调用这个方法public void onClickReset(View view) {running = false;seconds = 0;}private void runTimer() {//得到文本视图final TextView timeView = (TextView) findViewById(R.id.time_view);//创建一个新地Handlerfinal Handler handler = new Handler();//调用post()方法,传入一个新的Runnable。post()方法会立即运行代码handler.post(new Runnable() {public void run() {int hours = seconds / 3600;int minutes = (seconds%3600)/60;int secs = seconds % 60;//设置显示格式String time = String.format(Locale.getDefault(), "%d:%02d%02d", hours, minutes, secs);//设置文本视图timeView.setText(time);if (running) {++seconds;}//在1000ms后再次提交并运行Runnable中的代码,会反复调用handler.postDelayed(this, 1000);}});}
}

至此,一个基本秒表应用到此全部结束。
ps:不能直接在onCreate中写一个循环更新计时器,onCreate必须在屏幕显示之前完成,如果包含一个无线循环,这个方法将无法结束。

相关文章:

使用Handler创建一个Android秒表应用

本文所有代码都放在以下链接中&#xff1a;https://github.com/MADMAX110/Stopwatch 0、应用是一个有活动、布局和其他资源组成的集合。其中一个活动是应用的主活动。每个应用都有一个主活动&#xff0c;在文件AndroidManifest.xml中指定。 1、默认地&#xff0c;每个应用都在…...

node-sass安装失败解决方法总结

node-sass 安装失败的原因 npm 安装 node-sass 依赖时&#xff0c;会从 github.com 上下载 .node 文件。由于国内网络环境的问题&#xff0c;这个下载时间可能会很长&#xff0c;甚至导致超时失败。 解决方法一&#xff1a;使用淘宝镜像源&#xff08;推荐&#xff09; npm …...

C++特殊类设计

文章目录 1.设计一个类&#xff0c;不能被拷贝2.设计一个类&#xff0c;只能在堆上创建对象3.设计一个类&#xff0c;只能在栈上创建对象4.设计一个类&#xff0c;不能被继承5.设计一个类&#xff0c;只能创建一个对象5.1 单例模式5.2 饿汉模式5.3 懒汉模式5.4 两种模式的析构函…...

常用的python gpu加速方法

在使用 PyCharm进行机器学习的时候&#xff0c;我们常常需要自己创建一些函数&#xff0c;这个过程中可能会浪费一些时间&#xff0c;在这里&#xff0c;我们为大家整理了一些常用的 Python加速方法&#xff0c;希望能给大家带来帮助。 在 Python中&#xff0c;我们经常需要创建…...

SpringCloud-Gateway

什么是网关&#xff1f; 网关是一个服务&#xff0c;是访问内部系统的唯一入口&#xff0c;提供内部服务的路由中转&#xff0c;额外还可以在此基础上提供如身份验证、监控、负载均衡、限流、降级与应用检测等功能。 Spring Cloud Gateway 与 Zuul 对比 zuul1.x与zuul2.x Zu…...

【C++ qt4】操作json学习笔记

本博文源于笔者在学习c qt4操作json文件&#xff0c;qt4不支持json&#xff0c;里面的函数是json.h与jsoncpp.cpp我已经附在文末&#xff0c;大家可复制重命名用&#xff0c;里面的案例可以自己拿来敲或者直接copy也行.,一定利用好目录拖动&#xff0c;不然很长。 文章目录 1.从…...

【牛客刷题专栏】0x25:JZ24 反转链表(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录 前言问…...

useEffect

useEffect 1.依赖项是什么&#xff1f;2.useEffect怎么知道依赖项数组发生了改变&#xff1f;3.依赖项的改变会导致无限渲染吗&#xff1f;4.使用 Object.is 来比较新/旧 state 是否相等&#xff0c;浅比较&#xff1f;5.为什么要用浅比较&#xff0c;而不用深比较呢&#xff1…...

如何利用splice()和slice()方法操作数组

如何利用splice&#xff08;&#xff09;和slice&#xff08;&#xff09;方法操作数组 前言splice()是什么&#xff0c;有什么用&#xff1f;怎么用&#xff1f;slice()是什么&#xff0c;有什么用&#xff1f;怎么用&#xff1f;splice和slice方法的区别小结 前言 splice&am…...

一文读懂ChatGPT(全文由ChatGPT撰写)

最近ChatGPT爆火&#xff0c;相信大家或多或少都听说过ChatGPT。到底ChatGPT是什么&#xff1f;有什么优缺点呢&#xff1f; 今天就由ChatGPT自己来给大家答疑解惑~ 全文文案来自ChatGPT&#xff01; 01 ChatGPT是什么 ChatGPT是一种基于人工智能技术的自然语言处理系统&…...

如何提升应届生职场竞争力

引言 对于应届毕业生来说&#xff0c;进入职场是既令人兴奋又具有挑战性的。面对竞争激烈的就业市场&#xff0c;提高自身的职场竞争力对于应届生来说尤为重要。本文旨在为应届生提供有价值的见解和实用的策略&#xff0c;帮助他们提升职场竞争力&#xff0c;增加在就业市场中的…...

David Silver Lecture 5: Model-Free Control

1 Introduction 1.1 内容 上一章是对一个unknown MDP进行value function的预测&#xff0c;相当于policy evaluation。这一章是对unknown MDP找到一个最优的policy&#xff0c; optimise value function. 1.2 On and Off-Policy Learning On-policy learning learn on the…...

MySQL-----事务管理

文章目录 前言一、什么是事务二、为什么会出现事务三、事物的版本支持四、事物的提交方式五、事务常见的操作方式六、事务隔离级别如何理解隔离性1隔离级别查看与设置隔离性读未提交【Read Uncommitted】读提交【Read Committed】可重复读【Repeatable Read】串行化【serializa…...

chatGPT润色中英论文软件-文章修改润色器

chatGPT可以润色英文论文吗&#xff1f; ChatGPT可以润色英文论文&#xff0c;它具备自动纠错、自动完善语法和严格全面的语法、句法和内容结构检查等功能&#xff0c;可以对英文论文进行高质量的润色和优化。此外&#xff0c;ChatGPT还支持学术翻译润色、查重及语言改写等服务…...

MacOS下安装和配置Nginx

一、安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"按回车后&#xff0c;根据提示操作&#xff1a;输入镜像序号 --> 输入Y&#xff0c;回车等待brew安装完成即可。 在终端输入brew -v后&#xff0c;会提示…...

采用UWB(超宽频)技术开发的java版智慧工厂定位系统源码

室内定位系统源码&#xff0c;采用UWB定位技术开发的智慧工厂定位系统源码 技术架构&#xff1a;单体服务 硬件&#xff08;UWB定位基站、卡牌&#xff09; 开发语言&#xff1a;java 开发工具&#xff1a;idea 、VS Code 前端框架&#xff1a;vue 后端框架&#xff1a;s…...

【2023华为OD笔试必会20题--C语言版】《04 日志采集系统》——数组

本专栏收录了华为OD 2022 Q4和2023Q1笔试题目,100分类别中的出现频率最高(至少出现100次)的20道,每篇文章包括原始题目 和 我亲自编写并在Visual Studio中运行成功的C语言代码。 仅供参考、启发使用,切不可照搬、照抄,查重倒是可以过,但后面的技术面试还是会暴露的。✨✨…...

MySQL数据库——MySQL修改存储过程(ALTER PROCEDURE)

在实际开发过程中&#xff0c;业务需求修改的情况时有发生&#xff0c;所以修改 MySQL 中的存储过程是不可避免的。 MySQL 中通过 ALTER PROCEDURE 语句来修改存储过程。下面将详细讲解修改存储过程的方法。 MySQL 中修改存储过程的语法格式如下&#xff1a; ALTER PROCEDURE…...

ASEMI代理ADV7125JSTZ330原装ADI车规级ADV7125JSTZ330

编辑&#xff1a;ll ASEMI代理ADV7125JSTZ330原装ADI车规级ADV7125JSTZ330 型号&#xff1a;ADV7125JSTZ330 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LQFP-48 批号&#xff1a;2023 引脚数量&#xff1a;48 工作温度&#xff1a;-40C~85C 安装类型&#xff1a;表面…...

86盒IP对讲一键报警器

86盒IP对讲一键报警器 86盒IP对讲一键报警器&#xff1a;革命性保障生命安全的利器&#xff01; 随着科技的飞速发展&#xff0c;我们的生活变得越来越方便和智能化。而86盒IP对讲一键报警器更是在这种背景下应运而生。这款产品不仅无缝对接各种手机APP&#xff0c;也可以在智…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...