Android之旅十 多個方式實現計時功能

案例:我們要實現的功能是點擊按鈕開始計時,從0開始計時到10停止,點擊Main線程不會影響計時操作,運行如下
vcC0yrXP1tXiuPa5psTco6zPwsPmuPq087zSwLS31s/t0rvPwqO6PC9wPgo8cD612tK71ta3vcq9o7rKudPDSGFuZGxlctbQtcRwb3N0RGVsYXllZLe9t6ijujwvcD4KPHByZSBjbGFzcz0=”brush:java;”> /**
* 使用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”+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"+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{

	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"+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 *
*/

初學者,希望大傢一起交流分享經驗!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *