使用handler来实现计时操作

这篇博客记录了在Android开发中使用Handler进行计时操作的方法。通过创建Handler对象,复写handleMessage方法,并在run方法中定时发送空消息来实现计时。文中提到初版设计会导致线程持续开启,消耗性能,于是改进为在按钮点击事件中控制消息发送,从而避免不必要的资源消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近才开始工作,总感觉没有做出什么东西,也没有学到很多东西,之前想学学大神总结知识点,但有没那耐心,而且其中遇到的问题也比较多,但又不能什么都不做,所以从现在开始就把在工作中遇到的一些问题和方法记录下来,做个备忘和分享,如有错误,还请大家指正。

实现原理:

使用获取handler对象,复写其handleMessage方法,然后在其run方法中每隔一秒发送一次空消息,然handler不断地接收并处理该消息,其中的暂停和开始是通过一个boolean类型的标签来控制的,注意的是,要首先发送一个该类型的空消息来来让handler进入消息的处理机制开始sendEmptyMessageDelayed(1, 1000);进行循环发送。

废话不多说,直接上代码:

MainActivity代码:

package com.ygc.handlertimer;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity implements OnClickListener{
	Button mStartBtn,mStopBtn;
	TextView mTimeTextView;
	Handler mHandler;
	boolean isStart;
	long timeMinute;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStartBtn = (Button) findViewById(R.id.btn_start);
        mStopBtn = (Button) findViewById(R.id.btn_stop);
//        记得为按钮设置监听哦
        mStartBtn.setOnClickListener(this);
        mStopBtn.setOnClickListener(this);
        mTimeTextView = (TextView) findViewById(R.id.show_time);
//        模拟定时5分钟
        timeMinute = 5 * 60 * 1000;
//        在主线程中创建的handler本身就属于主线程,但是不指定的话,handler下会有警告的标注线
        mHandler = new Handler(getMainLooper()){

			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 1) {
						if (timeMinute > 0) {
							if (isStart) {
							timeMinute -= 1000;
							mTimeTextView.setText(""+timeMinute);
							Log.e("MainActivity", timeMinute+"");
							/*如果实在其他子线程中进行的UI刷新操作,可以获取到主线程的handler之后,
							使用runOnUiThread来刷新UI操作*/
//							mHandler.post(new Runnable() {
//								@Override
//								public void run() {
////									可以在这做相关的数据处理,昨晚数据处理使用runOnUiThread刷新主线程UI
//									runOnUiThread(new Runnable() {
//										@Override
//										public void run() {
//											mTimeTextView.setText(""+timeMinute);
//										}
//									});
//								}
//							});
							
						}
//							每隔一秒发送一次消息
							sendEmptyMessageDelayed(1, 1000);
						}
				}
			}
        	
        };
//        记得要发送消息之后,handler才能接收到消息,进行处理;
        mHandler.sendEmptyMessage(1);
        
    }
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_start:
			isStart = true;
			break;
		case R.id.btn_stop:
			isStart = false;
			break;
		default:
			break;
		}
	}

}
布局文件代码:

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ygc.handlertimer.MainActivity" >

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/btn_start"
        android:layout_alignBottom="@+id/btn_start"
        android:layout_toRightOf="@+id/show_time"
        android:text="结束计时" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="14dp"
        android:layout_toLeftOf="@+id/show_time"
        android:text="开始计时" />

    <TextView
        android:id="@+id/show_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="78dp"
        android:text="time"
        android:textSize="30sp" />

</RelativeLayout>

运行这种方法后发现线程子开启后就一直没有关闭,比较消耗性能,所以就在后面的按钮中加了判断,将线程的延迟发送消息移到了计时操作的内部,这样在按钮点击时才进行消息发送开启计时,避免了handler消息的一直发送。

下面是修改后的代码:

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity implements OnClickListener{
	Button mStartBtn,mStopBtn;
	TextView mTimeTextView;
	Handler mHandler;
	boolean isStart;
	long timeMinute;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStartBtn = (Button) findViewById(R.id.btn_start);
        mStopBtn = (Button) findViewById(R.id.btn_stop);
//        记得为按钮设置监听哦
        mStartBtn.setOnClickListener(this);
        mStopBtn.setOnClickListener(this);
        mTimeTextView = (TextView) findViewById(R.id.show_time);
//        模拟定时5分钟
        timeMinute = 5 * 60 * 1000;
//        在主线程中创建的handler本身就属于主线程,但是不指定的话,handler下会有警告的标注线
        mHandler = new Handler(getMainLooper()){
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 1) {
						if (timeMinute > 0) {
							if (isStart) {
							sendEmptyMessageDelayed(1, 1000);
							timeMinute -= 1000;
							mTimeTextView.setText(""+timeMinute);
							Log.e("MainActivity", timeMinute+"");
							/*如果实在其他子线程中进行的UI刷新操作,可以获取到主线程的handler之后,
							使用runOnUiThread来刷新UI操作*/
//							mHandler.post(new Runnable() {
//								@Override
//								public void run() {
////									可以在这做相关的数据处理,昨晚数据处理使用runOnUiThread刷新主线程UI
//									runOnUiThread(new Runnable() {
//										@Override
//										public void run() {
//											mTimeTextView.setText(""+timeMinute);
//										}
//									});
//								}
//							});
							
						}
//							每隔一秒发送一次消息
//							sendEmptyMessageDelayed(1, 1000);
						}
				}
			}
        	
        };
//        记得要发送消息之后,handler才能接收到消息,进行处理;
        mHandler.sendEmptyMessage(1);
    }
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_start:
			if (!isStart) {
				mHandler.sendEmptyMessage(1);
				isStart = true;
			}
			break;
		case R.id.btn_stop:
			if (isStart) {
				mHandler.removeMessages(1);
				isStart = false;
			}
			break;
		default:
			break;
		}
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值