进阶_计时器(Handler+Thread实现)_150503

来源:互联网 发布:java之gui编程 三 编辑:程序博客网 时间:2024/05/29 13:11

有三种实现计时器的方式:

1:最基本的Handler+Thread的方式,因为最近准备着手了解线程和消息机制,所以这一个会比较详细。

2:handler.postDelayed()方法,这个实现起来是最简单的,但是个人不太喜欢,因为递归这种东西,真的很难写。

3:Thread+TimeTask的方式;  其实这三个,最基础的是第一种。本文介绍的也是第一种,之后两种会在之后的blog里面贴上代码,不仔细介绍了。当然,也许还有其他的,我不知道罢了。


布局文件activity_main.xml

<RelativeLayout 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"    tools:context="fatenliyer.f_TimerOne.MainActivity" >    <TextView        android:id="@+id/tv_one"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:textSize="40sp" >    </TextView></RelativeLayout>

配置文件AndroidMainfest不需要做处理


第一个就是MainActivity.java ; 这里的作用就是 执行OnCreate方法,然后,开启一个线程

package fatenliyer.f_TimerOne;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;/** * 计时器,每秒钟增加 1 */public class MainActivity extends Activity {public static final int TIMER = 1;private TextView tvShow;        @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          tvShow = (TextView) findViewById(R.id.tv_one);                new Thread(new TimeThread(tvShow)).start();    }    }

接下来就是TimeThread线程; 这里新建了一个TimeHandler的消息处理机制,即每次sleep1000ms之后,就将一个消息传给handler,并且是永恒执行的(while(true))。当然,退出主线程也就会结束此子线程

package fatenliyer.f_TimerOne;import android.os.Message;import android.widget.TextView;/** * 线程, 计时线程 */public class TimeThread implements Runnable{private TimeHandler mHandler = new TimeHandler();private TextView mTv;public TimeThread(TextView tv) {this.mTv = tv;}@Overridepublic void run() {while(true){   // 这句话 表明一直执行try {Thread.sleep(1000);    // 1000 msMessage msg = new Message();msg.what = MainActivity.TIMER;msg.obj = mTv;mHandler.sendMessage(msg);System.out.println("send...");} catch (InterruptedException e) {e.printStackTrace();System.out.println("thread error...");}}}}

接下来就是最后一块Handler。 这里比较长的是changeTimerFormat,但是不用管它,它只是将秒数,转化成好看一点的字符串罢了。主要的还是 handlermessage(),是在这里确定了msg.what,然后取出msg.obj,并且执行显示到界面上的。

package fatenliyer.f_TimerOne;import android.os.Handler;import android.os.Message;import android.widget.TextView;/** * 计时器 的消息处理 */public class TimeHandler extends Handler{private long i = 0;private TextView mTv;TimeHandler(){}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == MainActivity.TIMER) {mTv = (TextView) msg.obj;mTv.setText(changeTimerFormat(++i));}}/** * 转化成显示的格式 * @param paramLong  * @return 待显示的字符串 */private String changeTimerFormat(long paramLong)  {    long day = paramLong / 86400;    long hour = paramLong % 86400 / 3600;    long minute = paramLong % 3600 / 60;    long second = paramLong % 60;        // 天数    String str1 = String.valueOf(day);    if (day == 0) {str1 = "";}else{str1 = str1 + "天";}    // 小时数    String str2 = String.valueOf(hour);    if (hour == 0) {str2 = "";}else if (hour < 10) {str2 = "0" + str2 + ":";}else {str2 = str2 + ":";}    // 分钟数    String str3 = String.valueOf(minute);    if (minute == 0) {str3 = "00" + ":";}else if (minute < 10) {str3 = "0" + str3 + ":";}else {str3 = str3 + ":";}    // 秒钟数    String str4 = String.valueOf(second);    if (second == 0) {str4 = "";}else if (second < 10) {str4 = "0" + str4;}        return str1 + str2 + str3 + str4;  }}

好了,代码就这样结束了。

总结一下,这个计时器的工作过程:

1,在MainActivity中开启一个线程,也就是TimerThread

2,在线程的run方法中,执行休眠1000ms, 并且休眠一次就传递一次消息给handler,然后由hander更新UI。

OK,这样我们也就容易理解Handler和Thread扮演的角色了:

Thread就好像是包身工,只管不停的做自己的事,然后,隔段时间就告诉包工头一次,告诉的方式就是msg,

Hander就是包工头,他就通过msg.what来确定是哪个包身工做的事, 通过msg.obj获得成品.


图片效果:




代码下载:

http://download.csdn.net/detail/u014803950/8656227





0 0
原创粉丝点击