Android之旅十 多个方式实现计时功能

案例:我们要实现的功能是点击按钮开始计时,从0开始计时到10停止,点击Main线程不会影响计时操作,运行如下   

上面,大家也看到了,我使用了不同的方式来实现这个功能,下面跟大家来分享一下:

第一种方式:使用Handler中的postDelayed方法:

    /**
	 * 使用Handler中的postDelayed计时
	 * @author Administrator
	 *
	 */
    class Button1ClickListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//我们没有调用countTime的start方法,所以它不能当做线程来处理
			handler1.post(countTime);
			//我们还可以使用如下代码来终止计时
			//handler.removeCallbacks(countTime);
		}
    }
    
    Handler handler1=new Handler();
    Runnable countTime=new Runnable() {
    	
    	int count=0;
		@Override
		public void run() {
			if(count<10){
				//打印出来和MainThread一样
				System.out.println("CountTime--->"+Thread.currentThread().getId());
				count++;
				show.setText("计时开始:"+count);
				//1s钟后再次执行countTime
				handler1.postDelayed(countTime, 1000);
			}
		}
	};


第二种方式:使用Handler中的sendMessage方法:

 

   /**
     * 使用Handler中的sendMessage进行计时
     * @author Administrator
     *
     */
    class Button2ClickListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			countTimeThread.start();
		}
    }
    
    Thread countTimeThread=new Thread(){
    	int count=0;
    	public void run() {
    		while(count<10){
    			try {
					Thread.sleep(1000);
					//打印出来和MainThread不同
					System.out.println("countTimeThread-->"+Thread.currentThread().getId());
					count++;
					//使用以下几种方式都可以
					Message msg=new Message();
	    			//Message msg=Message.obtain();
	   		        //Message msg=handler2.obtainMessage();
	    			msg.what=UPDATE;
	    			msg.obj=count;
	    			handler2.sendMessage(msg);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
    		}
    	};
    };
    
    Handler handler2=new Handler(){
    	@Override
    	public void handleMessage(Message msg) {
    		//打印出来和MainThread一样
    		System.out.println("handler2-->"+Thread.currentThread().getId());
    		if(msg.what==UPDATE){
    			show.setText("计时开始:"+msg.obj);
    		}
    	}
    };


第三种方式:使用Handler中的sendMessageDelayed方法:

  /**
     * 使用Handler中的sendMessageDelayed方法计时
     * @author Administrator
     *
     */
    class Button3ClickListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			Message msg=handler3.obtainMessage(UPDATE);
			handler3.sendMessageDelayed(msg, 1000);
		}
    }
    
    final Handler handler3=new Handler(){
    	int count=0;
    	public void handleMessage(Message msg) {
    		if(count<=10){
    			if(msg.what==UPDATE){
    				show.setText("计时开始:"+count);
    			}
    			Message message=handler3.obtainMessage(UPDATE);
    			handler3.sendMessageDelayed(message, 1000);
    			count++;
    		}
    	};
    };


第四中方式:使用AsyncTask

1)创建一个CountTimeAsyncTask继承自AsyncTask:

 

package com.xin.test;

import android.os.AsyncTask;
import android.widget.TextView;

public class CountTimeAsyncTask extends AsyncTask<Void, Integer, String>{

	private TextView textView;
	public CountTimeAsyncTask(TextView textView){
		this.textView=textView;
	}
	
	//该方法在UI线程中执行execute方法时会首次被调用,一般用来完成UI的初始化操作
	//该方法运行在UI线程中
	@Override
	protected void onPreExecute() {
		super.onPreExecute();
	}
	
	//执行完onPreExecute方法后,会执行下面的这个方法,传入的边长参数是在execute方法中传递过来的
	//注意如果是Void,在execute方法中所带的参数为null,如果不带参数会报错
	//该方法不运行在UI线程中
	@Override
	protected String doInBackground(Void... params) {
		int count=0;
		while(count<10){
			publishProgress(count);//调用该方法一次,下面的onProgressUpdate会被执行一次
			try {
				Thread.sleep(1000);
				count++;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return count+"";
	}

	//执行这个方法,可以用来更新UI中控件的变化,例如进度条信息变化等等
	//该方法运行在UI线程中
	@Override
	protected void onProgressUpdate(Integer... values) {
		int count=values[0];
		System.out.println(3);
		textView.setText("计时开始:"+count);
	}
	
	//doInBackground方法执行完后会执行该方法,可以用来提示用户异步操作结束
	@Override
	protected void onPostExecute(String result) {
		textView.setText("计时结束-->"+result);
	}
}


2)在UI线程中实例化CountTimeAsyncTask,并调用其execute方法执行该异步操作:

    /**
     * 使用AsyncTask进行计时
     * @author Administrator
     *
     */
    class Button4ClickListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//调用后只会执行一次
			AsyncTask countTimeTask=new CountTimeAsyncTask(show);
			//因为doInBackground中的参数为Void... params,所以这里必须传递参数,否则会报错
			countTimeTask.execute(null);
			//打印出和MainThread一样
			System.out.println("asyncTask--->"+Thread.currentThread().getId());
		}
    }


我们在主线程操作按钮中执行的代码就是一个吐司操作:

  /**
     * 主线程操作
     * @author Administrator
     *
     */
    class Button5ClickListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			Toast.makeText(MainActivity.this, "我是主线程", Toast.LENGTH_LONG).show();
		}
    	
    }

计时操作总结:
/**
 * 计时操作
 * 用第一种方式使用的是Handler中的postDelayed计时,因为里面设置的参数中Runnable我们并没有调用其实例化(countTime)的start方法,
 * 所以这里并不是线程,所以能够进行更新UI主线程操作,此时的Handler与Main处于同一线程中,也就是主线程中,所以能够更新UI
 * 用第二种方式使用的是Handler中的handMessage计时,我们用到了线程操作countTimeThread,所以更新线程的操作不能在线程中进行
 * 我们应该发送一个消息(sendMessage)交给Handler去处理,此时的Handler线程与Main线程处于同一线程中
 * 第三种方式使用Handler中的sendMessageDelayed发送消息,相隔多少时间发送,此时的Handler也是与Main处于同一线程中
 * 用第四种方式使用的是继承AsyncTask类,然后调用其execute方法进行计时操作,里面的操作和线程状况可参考前面的实例代码
 * 注意Activity中的单线程模式:所有的UI操作都是非线程安全的,并且我们只能在主线程(UI)线程中对UI进行更新操作
 * @author HarderXin *
 */

初学者,希望大家一起交流分享经验!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 中实现计时跳转页面的步骤如下: 1. 在布局文件中添加 TextView,例如: ``` <TextView android:id="@+id/tv_countdown" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" /> ``` 2. 在 Activity 中添加以下代码: ``` import android.content.Intent; import android.os.Bundle; import android.os.CountDownTimer; import android.widget.TextView; public class CountdownActivity extends AppCompatActivity { private TextView mTvCountdown; private CountDownTimer mCountDownTimer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_countdown); mTvCountdown = findViewById(R.id.tv_countdown); // 创建倒计时器,倒计时时间为 5 秒,每隔 1 秒更新一次 mCountDownTimer = new CountDownTimer(5000, 1000) { @Override public void onTick(long millisUntilFinished) { // 更新倒计时文本 mTvCountdown.setText(String.format("%d 秒后跳转", millisUntilFinished / 1000)); } @Override public void onFinish() { // 倒计时结束,跳转到目标页面 Intent intent = new Intent(CountdownActivity.this, TargetActivity.class); startActivity(intent); finish(); } }; // 开始倒计时 mCountDownTimer.start(); } @Override protected void onDestroy() { super.onDestroy(); // 取消倒计时器 if (mCountDownTimer != null) { mCountDownTimer.cancel(); } } } ``` 其中,`CountDownTimer` 类用于创建倒计时器,有两个参数:倒计时时间和更新间隔。在 `onTick()` 方法中更新倒计时文本,并在 `onFinish()` 方法中跳转到目标页面。在 Activity 的 `onDestroy()` 方法中取消倒计时器,避免内存泄漏。 3. 在 AndroidManifest.xml 文件中添加以下代码: ``` <activity android:name=".CountdownActivity"/> <activity android:name=".TargetActivity"/> ``` 其中,`TargetActivity` 是目标页面的 Activity,需要在 AndroidManifest.xml 文件中进行注册。 注意:在使用计时跳转页面时,需要注意一些细节问题,例如在倒计时期间不允许用户进行其他操作,需要禁用返回按钮、禁止触摸屏幕等。另外,倒计时时间不宜设置过长,以免影响用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值