Handler会关联一个单独的线程和消息队列。Handler默认关联主线程,虽然要提供Runnable参数,但默认是直接调用Runnable中的run()方法。也就是默认下会在主线程执行,如果在这里面的操作会有阻塞,界面也会卡住。如果要在其他线程执行,可以使用HandlerThread。
HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。
- <span style="font-size: 12px;">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);
- }
- };
- }
- </span>
上面代码System.out输出线程ID相同
- <span style="font-size: 12px;">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());
- }
- };
- }</span>
从上面代码看线程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