Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Handler機制實例

Handler機制實例

編輯:關於Android編程

AndroidManifest.xml



    

    
        
            
                

                
            
        
        
        
        
        
        
        
    



MainActivity.java

 

 

package com.cctvjiatao.handlerdemo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * Handler機制原理詳見:http://blog.csdn.net/jiayi_yao/article/details/51082073
 */
public class MainActivity extends Activity {

	private final String TAG = getClass().getSimpleName();
	private Context context;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		context = this;
		setContentView(R.layout.activity_main);
		initView();
	}

	private void initView() {
	    Button btn1 = (Button) findViewById(R.id.btn1);
	    Button btn2 = (Button) findViewById(R.id.btn2);
	    Button btn3 = (Button) findViewById(R.id.btn3);
	    Button btn4 = (Button) findViewById(R.id.btn4);
	    Button btn5 = (Button) findViewById(R.id.btn5);
	    
	    btn1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(context, SendMsgAct.class));
				
			}
		});
	    
	    btn2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(context, PostDelayedAct.class));
				
			}
		});
	    
	    btn3.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(context, SendMsgProgressbarAct.class));
				
			}
		});
	    
	    btn4.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(context, IsSameThreadAct.class));
				
			}
		});
	    
	    btn5.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(context, SendMsgLooperAct.class));
				
			}
		});
    }

}

activity_main.xml

 

 



SendMsgAct.java

 

 

package com.cctvjiatao.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Button;

/**
 * @作者: jiatao
 * @修改時間:2016-4-10 下午10:55:26
 * @包名:com.cctvjiatao.handlerdemo
 * @文件名:SendMsgAct.java
 * @版權聲明:www.cctvjiatao.com
 * @功能: 不斷變化的按鈕
 */
public class SendMsgAct extends Activity {

	private final String TAG = getClass().getSimpleName();
	private MyHandler mMyHandler;
	private Button btn_variable;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_sendmsg);
		btn_variable = (Button) findViewById(R.id.btn_variable);

		mMyHandler = new MyHandler();

		MyThread m = new MyThread();
		new Thread(m).start();
	}

	class MyHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Log.e(TAG, "handleMessage...");
			Bundle b = msg.getData();
			String btnStr = b.getString("name");
			btn_variable.append(btnStr);
		}
	}

	class MyThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				Message msg = new Message();
				Bundle b = new Bundle();
				b.putString("name", "Monkey");
				msg.setData(b);
				SendMsgAct.this.mMyHandler.sendMessage(msg);
				Log.e(TAG, "sendMessage...");
			}
		}

	}

}

PostDelayedAct.java

 

 

package com.cctvjiatao.handlerdemo;

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

/**
 * @作者: jiatao
 * @修改時間:2016-4-10 下午11:55:26
 * @包名:com.cctvjiatao.handlerdemo
 * @文件名:PostDelayedAct.java
 * @版權聲明:www.cctvjiatao.com
 * @功能: Handler.postDelayed + Runnable 
 * 		這個例子是最簡單的介紹handler的使用:是將handler綁定到它所建立的線程中.
 */
public class PostDelayedAct extends Activity {

	private final String TAG = getClass().getSimpleName();
	private TextView tv_msg;
	private Button btn_start, btn_end;
	
	Handler handler = new Handler();
	Runnable rb = new Runnable(){
		public void run() {
			//線程每次執行時輸出"UpdateThread..."文字,且自動換行
			tv_msg.append("\nUpdateThread...");
			//延時3s後又將線程加入到線程隊列中
			handler.postDelayed(rb, 3000);//可以嘗試注釋本行代碼,觀察變化
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_postdelayed);
		initView();
	}

	private void initView() {
		tv_msg = (TextView) findViewById(R.id.tv_msg);
		btn_start = (Button) findViewById(R.id.btn_start);
		btn_end = (Button) findViewById(R.id.btn_end);
		
		btn_start.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				 //將線程接口立刻送到線程隊列中
				handler.post(rb);
				Log.e(TAG, "start...");
			}
		});
		
		btn_end.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				//將線程接口從線程隊列中移除
				handler.removeCallbacks(rb);
				Log.e(TAG, "end...");
			}
		});
	    
    }

}

SendMsgProgressbarAct.java

 

 

package com.cctvjiatao.handlerdemo;

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.ProgressBar;
import android.widget.TextView;

/**
 * @作者: jiatao
 * @修改時間:2016-4-10 下午11:55:26
 * @包名:com.cctvjiatao.handlerdemo
 * @文件名:SendMsgProgressbarAct.java
 * @版權聲明:www.cctvjiatao.com
 * @功能: 例子中用到了handler的消息隊列機制,
 * 		即通過handler中一個線程向消息隊列中用sendMessage方法發送消息,發送的消息當然可以用來傳遞參數。
 * 		在handler中用handleMessage來處理消息,處理方法是獲得消息隊列中的消息參數,用這些參數來完成另外一些功能。
 */
public class SendMsgProgressbarAct extends Activity {

	private final String TAG = getClass().getSimpleName();
	private ProgressBar pb_handler;
	private Button btn_start;
	
	//創建一個handler,內部完成處理消息方法
	Handler handler = new Handler(){
		public void handleMessage(Message msg) {
			Log.e(TAG, "sendMessage...");
			//顯示進度條
			pb_handler.setProgress(msg.arg1);
			//重新把進程加入到進程隊列中
			handler.post(rb);//注釋本行代碼,觀察變化
		};
	};
	
	Runnable rb = new Runnable(){
		int i = 0;
		public void run() {
			i += 10;
			//首先獲得一個消息結構
			Message msg = handler.obtainMessage();
			//給消息結構的arg1參數賦值
			msg.arg1 = i;
			//延時1s,java中的try+catch用來排錯處理
			try {
	            Thread.sleep(1000);
            } catch (InterruptedException e) {
	            e.printStackTrace();
            }
			//把消息發送到消息隊列中
			handler.sendMessage(msg);
			Log.e(TAG, "sendMessage...");
			if(i == 100){
				//把線程從線程隊列中移除
				handler.removeCallbacks(rb);
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_progressbar);
		initView();
	}

	private void initView() {
		pb_handler = (ProgressBar) findViewById(R.id.pb_handler);
		btn_start = (Button) findViewById(R.id.btn_start);
		
		btn_start.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				pb_handler.setVisibility(View.VISIBLE);
				 //將線程接口立刻送到線程隊列中
				handler.post(rb);
				Log.e(TAG, "start...");
			}
		});
		
    }

}

IsSameThreadAct.java

 

 

package com.cctvjiatao.handlerdemo;

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

/**
 * @作者: jiatao
 * @修改時間:2016-4-10 下午11:55:26
 * @包名:com.cctvjiatao.handlerdemo
 * @文件名:IsSameThreadAct.java
 * @版權聲明:www.cctvjiatao.com
 * @功能: 驗證僅使用handler的post方法是否處於同一個線程
 * 		例子PostDelayedAct和例子SendMsgProgressbarAct表面上看handler使用了post方法啟動了runnbale,
 * 		其實啟動的線程和activity主線程是同一個線程,因為它只是運行了線程的run方法,而不是start方法。
 */
public class IsSameThreadAct extends Activity {

	private final String TAG = getClass().getSimpleName();
	
	//新建一個handler
	Handler handler = new Handler();
	
	Runnable rb = new Runnable(){
		public void run() {
			//打印新建線程信息
			Log.e(TAG, "handler_id---->"+Thread.currentThread().getId());
			Log.e(TAG, "handler_name---->"+Thread.currentThread().getName());
			//延時10s,為了觀察主界面中內容出現的時間
			try {
	            Thread.sleep(3000);
            } catch (InterruptedException e) {
	            e.printStackTrace();
            }
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//將runnable加載到handler的線程隊列中去
		handler.post(rb);
		/*Thread t = new Thread(rb);
		t.start();*/
		setContentView(R.layout.act_postdelayed);
		//打印activtiy線程信息
		Log.e(TAG, "activity_id---->"+Thread.currentThread().getId());
		Log.e(TAG, "activity_name---->"+Thread.currentThread().getName());
	}

}
/**
 * 結果說明這兩個線程確實是同一線程,並且可以看出主界面中的文字大概過了10s才顯示出來,
 * 因為語句setContentView(R.layout.activity_main);放在了handler的post啟動語句後面,
 * 而handler綁定的線程中又延時了10s,所以同時也證明了只有是同一個線程才會出現這種情況。
 */

/**
 * 如果把語句:
 * 		handler.post(rb);
 * 換成:
 * 		Thread t = new Thread(rb);
 * 		t.start();
 * 其它的不變,則程序運行時主界面內容立刻就顯示出來了,且打印日志為。。。
 * 這兩者都說明這樣綁定的線程與它所在的activity線程就不是同一個線程了。
 */

SendMsgLooperAct.java

 

 

package com.cctvjiatao.handlerdemo;

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

/**
 * @作者: jiatao
 * @修改時間:2016-4-10 下午11:55:26
 * @包名:com.cctvjiatao.handlerdemo
 * @文件名:SendMsgLooperAct.java
 * @版權聲明:www.cctvjiatao.com
 * @功能: 學會使用怎樣在新線程中處理消息的方法
 *      1)這個例子將學會怎樣不使用runnable來啟動一個線程,而是用HandlerThread的looper來構造一個handler,
 *      	然後該handler自己獲得消息,並傳遞數據,然後又自己處理消息,當然這是在另一個線程中完成的。
 *      2)消息結構中傳遞簡單的整型可以采用它的參數arg1和arg2,或者傳遞一些小的其它數據,
 *      	可以用它的object,該object可以是任意的對象。
 *      	當需要傳送比較大的數據是,可以使用消息的setData方法,該方法需要傳遞一個Bundle的參數。
 *      	Bundle中存放的是鍵值對的map,只是它的鍵值類型和數據類型比較固定而已。
 */
public class SendMsgLooperAct extends Activity {

	private final String TAG = getClass().getSimpleName();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_postdelayed);
		Log.e(TAG, "activity_ID---->" + Thread.currentThread().getId());
		Log.e(TAG, "activity_Name---->" + Thread.currentThread().getName());
		
		// 新建一個HanderThread對象,該對象實現了用Looper來處理消息隊列的功能		
		HandlerThread handler_thread = new HandlerThread("handler_thread");
		handler_thread.start();
		
		// MyHandler類是自己繼承的一個類,這裡采用hand_thread的Looper來初始化它
		MyHandler my_handler = new MyHandler(handler_thread.getLooper());
		// 獲得一個消息msg
		Message msg = my_handler.obtainMessage();
		// 采用Bundle保存數據,Bundle中存放的是鍵值對的map,只是它的鍵值類型和數據類型比較固定而已
		Bundle b = new Bundle();
		b.putString("whether", "晴天");
		b.putInt("temperature", 34);
		msg.setData(b);
		// 將msg發送到自己的handler中,這裡指的是my_handler,調用該handler的HandleMessage方法來處理該mug
		msg.sendToTarget();
	}

	class MyHandler extends Handler {
		// 空的構造函數
		public MyHandler() {
			
		}
		// 以Looper類型參數傳遞的函數,Looper為消息泵,不斷循環的從消息隊列中得到消息並處理,
		// 因此,每個消息隊列都有一個Looper,因為Looper是已經封裝好了的消息隊列和消息循環的類
		public MyHandler(Looper looper) {
			// 調用父類的構造函數
			super(looper);
		}

		@Override
		public void handleMessage(Message msg) {
			Log.e(TAG, "Handler_ID---->" + Thread.currentThread().getId());
			Log.e(TAG, "Handler_Name---->" + Thread.currentThread().getName());
			// 將消息中的bundle數據取出來
			Bundle b = msg.getData();
			String whether = b.getString("whether");
			int temperature = b.getInt("temperature");
			Log.e(TAG, "Handler_ID---->" + "whether= " + whether + " ,temperature= " + temperature);
		}

	}
}

act_sendmsg.xml

 

 



    


act_postdelayed.xml

 

 



    

    



 

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved