Mars視頻之Handler筆記【持續更新】


前言:Android開發當中,絕大多數的UI操作都應該在主線程當中進行,主線程之外原則上不允許修改View(progressBar等特殊控件除外)。在一個應用程序當中,主線程通常用於接收用戶的輸入信息,以及將運算的結果反饋給用戶,因此,對一些可能會產生阻塞的操作,必須放置在WorkerThread(子線程)中,但WorkerThread中的參數又不能反饋給主線程,因此就產生了一種通信方法:Handler!


一.1.Handler用來處理主線程與子線程之間的數據傳輸。

  作用:把消息放到消息隊列中。

     2.Looper:消息隊列循環器,不斷的從消息隊列中取出消息,取出的消息會再交給Handler來處理。如果消息隊列沒有消息,Looper會等待,該線程就會出現阻塞。

Java Code:

package com.gu.aatest;

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

public class MainActivity extends Activity {

	private Button mButton;
	private TextView mTextView;
	private Handler handler;

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

		mButton = (Button) findViewById(R.id.button);
		mTextView = (TextView) findViewById(R.id.textview);
		handler = new FirstHandler();

	    mButton.setOnClickListener(new OnClickListener() {

	        @Override
			public void onClick(View v) {
				// obtainMessage() 獲取一個消息對象
				Message msg = handler.obtainMessage();
				// what爲msg的屬性
				msg.what = 2;
				/**
				 * 將消息放到消息隊列中
				 * 
				 * 步驟:1.Looper取出消息;2.Looper將會找到與消息對象對應的Handler對象;3.L
				 * ooper將會調用Handler的handleMessage()方法來處理信息對象
				 */
				handler.sendMessage(msg);
			}
		});
	}

	class FirstHandler extends Handler {

	    // 用來處理消息的handleMessage()方法
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			int what = msg.what;
			System.out.println("what:" + what);
		}
	}
}
二.子線程向主線程發送消息

package com.gu.aatest;

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

public class MainActivity extends Activity {

	private Button mButton;
	private TextView mTextView;
	private Handler handler;

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

		mButton = (Button) findViewById(R.id.button);
		mTextView = (TextView) findViewById(R.id.textview);
		handler = new FirstHandler();

	    mButton.setOnClickListener(new OnClickListener() {

	        @Override
			public void onClick(View v) {
				// obtainMessage() 獲取一個消息對象
				Thread t = new NetWorkThread();
				t.start();
			}
		});
	}

	class FirstHandler extends Handler {

	    // 用來處理消息的handleMessage()方法
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			System.out.println("FirstHandler--當前線程爲:"
					+ Thread.currentThread().getName());
			String s = (String) msg.obj;
			mTextView.setText(s);
		}
	}

	// 模擬從網絡加載數據
	class NetWorkThread extends Thread {

		/**
		 * 重載方法
		 */
		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				Thread.sleep(2 * 1000);
				System.out.println("NetWorkThread--當前線程爲:"
						+ Thread.currentThread().getName());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			String s = "從網絡加載數據";
			// 此處不能直接用TextView。setText(s)來顯示,否則會報錯
			Message msg = handler.obtainMessage();
			// sendMessage(msg)方法無論在主線程還是子線程都能發送
			handler.sendMessage(msg);

		}

	}

}

打印結果如下,下面的main爲主線程,其餘爲子線程



三.主線程向子線程發送消息

package com.gu.aatest;

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

public class MainActivity extends Activity {

	private Button mButton;
	private TextView mTextView;
	private Handler handler;

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

		mButton = (Button) findViewById(R.id.button);
		mTextView = (TextView) findViewById(R.id.textview);
		Thread thread = new NetWorkThread();
		thread.start();
		mButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// obtainMessage() 獲取一個消息對象
				Message msg = handler.obtainMessage();
				handler.sendMessage(msg);
				System.out.println("當前線程爲:" + Thread.currentThread().getName());
			}
		});
	}

	// 模擬從網絡加載數據
	class NetWorkThread extends Thread {

		/**
		 * 重載方法
		 */
		@Override
		public void run() {
			// TODO Auto-generated method stub
			// 準備Looper
			Looper.prepare();
			handler = new Handler() {

				/**
				 * 重載方法
				 * 
				 * @param msg
				 */
				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					System.out.println("NetWorkThread--當前線程爲:"
							+ Thread.currentThread().getName());
					System.out.println("收到消息");
				}

			};
			/**
			 * 調用Looper的Loop()方法後,Looper對象將不斷的從消息隊列中取出消息對象,
			 * 然後調用handler的handleMessage()方法處理消息對象,如果消息隊列中沒有了消息對象,則會線程阻塞
			 */
			Looper.loop();
		}

	}

}

輸出結果如下;





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章