Thread、Handler与HandlerThread、Handler使用

Handler会关联一个单独的线程和消息队列。Handler默认关联主线程,虽然要提供Runnable参数,但默认是直接调用Runnable中的run()方法。也就是默认下会在主线程执行,如果在这里面的操作会有阻塞,界面也会卡住。如果要在其他线程执行,可以使用HandlerThread

HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。

package com.goma.handlertwo;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

public class HandlerActivity extends Activity {
    private Handler handler = null;
    private ProgressBar progressBar = null;
    private int i = 0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_handler);
		
		progressBar = (ProgressBar)findViewById(R.id.pb_id);
		Button start = (Button)findViewById(R.id.start);
		Button stop = (Button)findViewById(R.id.stop);
		
		System.out.println("HandlerActivity:::::"+Thread.currentThread().getId());
		
		handler = new Handler(new Handler.Callback() {
			@Override
			public boolean handleMessage(Message msg) {
				// TODO Auto-generated method stub
				System.out.println("Handler.CallBack::::" + Thread.currentThread().getId());
				progressBar.setProgress(msg.arg1);
				progressBar.setSecondaryProgress(msg.arg1 + 5 );
				return false;
			}
		});
		
		start.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				handler.post(run);
			}
		});
		
		stop.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				handler.removeCallbacks(run);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.handler, menu);
		return true;
	}
	
	Runnable run = new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			System.out.println("##########"+Thread.currentThread().getId());
			handler.postDelayed(run, 2000);
			Message msg = handler.obtainMessage();
			msg.arg1 = i * 10 ;
			i++;
			handler.sendMessage(msg);
		}
	};
}

    上面代码System.out输出线程ID相同

package com.goma.handlerthreaddemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class HandlerThreadActivity extends Activity {
	Handler handler = null;

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

		System.out.println("------------------>" + Thread.currentThread().getId());

		HandlerThread ht = new HandlerThread("MyThread");
		ht.start();
		handler = new Handler(ht.getLooper(), new Handler.Callback() {
			@Override
			public boolean handleMessage(Message msg) {
				// TODO Auto-generated method stub
				int tmp = msg.arg1;
				System.out.println(Thread.currentThread().getId() + "::::::::::::" + tmp);
				return false;
			}
		});

		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				handler.post(run);
			}
		});

		Button btn2 = (Button) findViewById(R.id.btn2);
		btn2.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				handler.removeCallbacks(run);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.handler_thread, menu);
		return true;
	}

	Runnable run = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			handler.postDelayed(run, 5000);
			Message msg = handler.obtainMessage();
			msg.arg1 = 1123;
			handler.sendMessage(msg);
			System.out.println("###################" + Thread.currentThread().getId());
		}
	};
}

    从上面代码看线程ID是不同的,有两个一个主线程、一个HandlerThread线程

    ==========================================================

    另:我在学习HandlerThread、Thread时,我就向为什么不:

    Thread t = new Thread(Runnable);

    t.start();

    后来弄明白了,其实Runnable是在Handler执行的,但是Handler默认绑定主线程,

    所以采用这种方法,在Thread.start()确是新生成一个线程,但是在Handler.post(Runnable)后,

    runnable方法又会被绑定到主线程中执行。

    ==========================================================================

    另可参考:http://blog.sina.com.cn/s/blog_5da93c8f0101kio1.html

猜你喜欢

转载自oma1989.iteye.com/blog/1991880