实验目的

熟悉和掌握Android线程的使用

实验要求

  1. 完成一个秒表,具备启停功能,正确使用工作线程完成界面刷新
  2. 分析秒表的计时是否准确,原因是什么,如何保证秒表计时准确?

实验过程

实验结果

实验代码

界面部分

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="秒表"
android:textAlignment="center"
android:textSize="40dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="00:00:00"
android:id="@+id/tv_time"
android:textAlignment="center"
android:textSize="60dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Space
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_weight="1"
/> <Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清零"
android:textColor="#000000"
android:textSize="25dp"
android:background="#99FFFF"/> <Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="计时"
android:layout_weight="1"
android:textSize="25dp"
android:background="#FFC8B4"
/>
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"
android:layout_weight="1"
android:textSize="25dp"
android:background="#CCFF99"
/>
</LinearLayout>
</LinearLayout>

核心代码

Timer.java

package com.example.administrator.exp5;

import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class Timer extends AppCompatActivity {
private static Handler handler = new Handler();
private static TextView tv_time = null;
private static Button btn_clear,btn_start,btn_stop; private static String time; private int min=0,sec=0,psec= 0; boolean runflag = true;
int status = 0; // 0 - clear ; 1 - start ; 2 - stop
long last,templast = -1; String str=""; private Thread workThread; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); tv_time = (TextView)findViewById(R.id.tv_time);
btn_clear = (Button)findViewById(R.id.btn_clear);
btn_start = (Button)findViewById(R.id.btn_start);
btn_stop = (Button)findViewById(R.id.btn_stop); workThread = new Thread(null,RefreshLabel,"workThread");
workThread.start();
last = System.currentTimeMillis(); btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//计时开始
status = 1;
if(templast != -1)
{
last = templast;
}
}
});
btn_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//停止计时
status = 2;
templast = last;
}
});
btn_clear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
min = sec = psec = 0;
//清零
status = 0;
last = System.currentTimeMillis();
tv_time.setText("00:00:00");
templast = -1;
}
});
} private Runnable RefreshLabel = new Runnable() {
@Override
public void run() {
try{
while(runflag)
{
Thread.sleep(50);
if(status == 1)
{
int t=0;
long tmp = System.currentTimeMillis();
long cha = tmp - last; t = (int)cha/1000;
psec = (int)cha - t * 1000;
psec %= 100;
sec = t - ((int)t/60)*60;
min = (int)t/60;
if(min == 60)
{
min = 0;
}
str = "";
str = str + String.format("%02d",min) + ":" +String.format("%02d",sec) + ":" + String.format("%02d",psec); tv_time.post(new Runnable() {
@Override
public void run() {
tv_time.setText(str);
}
});
}
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
};
}

设计思路

    秒表需要完成停启功能,也就是说需要能够停下来,而且在停下来以后需要能够继续计时。这个计时的工作需要交付给一个子进程来做,每隔一段时间就刷新一次界面,从而达到计时的效果。

    如何使秒表计时更加准确?可以通过sleep(1000)来计时,或者采取不断访问系统时间的方式来计时。两种方式相比较,第二种方式更加准确,第一种解决方案由于sleep时间是人为设定的,跟手机的性能有一定关系,除此之外,由于程序间断性执行,这些时间也会计算到总时间中,所以第一种方案计时不准确。应该采用第二种计时方式。

实验总结

    本实验主要是练习线程的使用,线程需要实现\(Runnable\)借口,并重载\(run()\)函数,在该函数中写入秒表运行的代码,进行计算:

private Runnable RefreshLabel = new Runnable(){
@Override
public void run(){
try{ }
catch(InterruptedException e){
e.printStackTrace();
}
}
}

然后创建Thread对象,将Runnable对象作为参数传递给Thread对象。

private Thread workThread;
workThread = new Thread(null,RefreshLabel,"workThread")

需要的三个参数,第一个参数表示线程组,第二个参数是需要执行的Runnable对象,第三个参数是参数名称。

关于时间计算:

通过System.currentTimeMillis()函数返回当前计算机的时间所对应的毫秒数。

时间换算如下:

1min = 60s

1s = 1000ms

时间计算部分代码:

long tmp = System.currentTimeMillis();
long cha = tmp - last;
t = (int)cha/1000;
psec = (int)cha - t * 1000;
psec %= 100;
sec = t - ((int)t/60)*60;
min = (int)t/60;
if(min == 60)
{
min = 0;
}
str = "";
str = str + String.format("%02d",min) + ":" +String.format("%02d",sec) + ":" + String.format("%02d",psec);

另外,由于单线程中,不能再UI线程外访问Android UI 工具包,则调用\(View.post()\)方法,进行异步通信。实现界面的动态更新。

【Android实验】线程的使用-计时器的更多相关文章

  1. android操作线程各种方法解析

    (一)刚开始学习android的时候我是这么写的 new Thread( new Runnable() { public void run() { myView.invalidate(); } }). ...

  2. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

  3. android 进程/线程管理(一)----消息机制的框架

    一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...

  4. Android子线程真的不能更新UI么

    Android单线程模型是这样描述的: Android UI操作并不是线程安全的,并且这些操作必须在UI线程执行 如果在其它线程访问UI线程,Android提供了以下的方式: Activity.run ...

  5. android 进程/线程管理(二)----关于线程的迷思

    一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...

  6. android 进程/线程管理(三)----Thread,Looper / HandlerThread / IntentService

    Thread,Looper的组合是非常常见的组合方式. Looper可以是和线程绑定的,或者是main looper的一个引用. 下面看看具体app层的使用. 首先定义thread: package ...

  7. android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)

    继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) ...

  8. android 进程/线程管理(四)----消息机制的思考(自定义消息机制)

    关于android消息机制 已经写了3篇文章了,想要结束这个系列,总觉得少了点什么? 于是我就在想,android为什么要这个设计消息机制,使用消息机制是现在操作系统基本都会有的特点. 可是andro ...

  9. Android子线程更新UI的方法总结

    版权声明:本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=6121280 消息机制,对于Android开发者来说,应该是非常 ...

  10. 《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

    第11章 Android的线程和线程池 11.1 主线程和子线程 (1)在Java中默认情况下一个进程只有一个线程,也就是主线程,其他线程都是子线程,也叫工作线程.Android中的主线程主要处理和界 ...

随机推荐

  1. mysql 内置功能 视图介绍

    之前的多表查询本质是把多张有关系的表连接在一起组成一张虚拟表,从而进行查询 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名], 用户使用时只需使用[名称]即 ...

  2. Canvas标签基础

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 文件操作(CRT、C++、WIN API、MFC)

    一.使用CRT函数文件操作 二.使用标准C++库 std::fstream std::string 1)std::string对象内部存储了一个C的字符串,以'\0'结尾的. 2)std::strin ...

  4. <<Joint Deep Modeling of Users and Items Using Reviews for Recommendation>> 评论打分预测

    综述: 本文将 CNN 与 FM(Factorization Machine) 结合,基于评论文本来进行评分预测. 简介: 目前将神经网络应用推荐系统的研究工作中,有一类思路是把如CNN等神经网络作为 ...

  5. LoadRunner11支持的浏览器小结-Loadrunner11打不开IE浏览器的问题

    http://www.cnblogs.com/qmfsun/p/4807237.html

  6. Postman: Pre-request Script,设置body 变量

    1)Postman Pre-request Script 设置变量名 2)把变量放在body里 3)Send后查看变量是否被替换

  7. 数据仓库基础(十)Informatica 组件1

    本文转载自:http://www.cnblogs.com/evencao/p/informatica.html Informatica主要的组件: Source Qualifier 从数据源读取数据 ...

  8. 最新版Intellij IDEA插件JRebel 7.0.7官方免费激活

    本文转自:http://blog.csdn.net/u012283609/article/details/70213307 开场语 有时候真实比小说更加荒诞,因为虚构是在一定逻辑下进行的,而现实往往毫 ...

  9. 360在线网站安全检测,web安全测试AppScan扫描工具,XSS常用的攻击手法

    360在线网站安全检测,web安全测试AppScan扫描工具,XSS常用的攻击手法 如何做好网站的安全性测试 360网站安全检测 - 在线安全检测,网站漏洞修复,网站后门检测http://websca ...

  10. Jmeter--正则表达式提取器

    正则提取器的一般使用场景是, 在我第二个请求参数中需要加入第一个请求的返回值, 此时通过正则提取器可以提取第一个请求返回值中指定的字段信息并赋值, 在第二个请求参数中直接引用该变量即可 jmeter的 ...