Android handler学习笔记
- 调用Message.obtain()从消息池中获得一个message对象,而不是直接new一个message对象,可以节省内存开销。也可以用handler.obtainMessage(),其实是一样的,obtainMessage()就是返回Message.obtain()
- message.sendToTarget()跟handler.sendMessage()是一样的
- 下面的方式可以拦截Message。
private Handler handler=new Handler(new Callback(){ public boolean handleMessage(Message msg){ //在Callback中可以拦截掉message //这里返回true以后就不会再执行下面的那个handleMessage。 if(msg.what==1)return true; return false; } }){ public void handleMessage(Message msg){ //处理消息 } };
- Handler发送消息,加入MessageQueue队列。Looper接收Handler发过来的消息,轮询MessageQueue队列,然后回传给Handler。
- Message绑定handler。可以用
Message msg=handler.obtainMessage(); msg.sendToTarget(); Message msg=Message.obtain(handler); msg.sendToTarget(); Message msg=Message.obtain(); handler.sendMessage(msg); 或者手动绑定,使用 msg.setTarget(handler);
- HandlerThread自动包含Looper,不需要手动创建,用起来方便。
- 因为主线程中默认包含了一个Looper,所以不需要再传入Looper。在子线程中使用Handler则需要传入一个thread的looper进去,而如果thread是handlerThread,可以直接用handlerThread.getLooper()拿到looper。如果是自己写的一个thread,在里面创建一个looper,因为不同线程处理,很可能报空指针错误。
- 为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。用HandlerThread可以省事。
- Handler会关联一个单独的线程和消息队列。
- 只有在run中的东西才是运行在子线程中的。
下面做了一个例子,handler例子:
package com.ac.handlertest; 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.TextView; public class MainActivity extends Activity implements OnClickListener { private Layout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initLayout(); initValue(); } private void initLayout() { layout = new Layout(); layout.helloText = (TextView) findViewById(R.id.helloText); layout.button1 = (Button) findViewById(R.id.button1); layout.button2 = (Button) findViewById(R.id.button2); layout.button3 = (Button) findViewById(R.id.button3); layout.button1.setOnClickListener(this); layout.button2.setOnClickListener(this); layout.button3.setOnClickListener(this); } private void initValue() { layout.helloText.setText(""); layout.button1.setText("1.主线程的Handler"); layout.button2.setText("2.普通子线程的Handler"); layout.button3.setText("3.使用HandlerThread"); } private class Layout { TextView helloText; Button button1; Button button2; Button button3; } // 1.主线程的Handler private void method_1() { new Handler().postDelayed(new Runnable() { @Override public void run() { Log.i("msg", "" + Thread.currentThread());//主线程 layout.helloText.setText("因为主线程中默认包含了一个Looper,所以不需要再传入Looper。"); } }, 1000); } // 2.普通子线程的Handler private void method_2() { Thread thread = new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Handler handler = new Handler() { public void handleMessage(Message msg) { Log.i("msg", "" + Thread.currentThread());//子线程myThread1 runOnUiThread(new Runnable() { public void run() { layout.helloText .setText("为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。"); } }); }; }; try { Thread.sleep(1000); handler.sendEmptyMessage(0); } catch (InterruptedException e) { e.printStackTrace(); } Looper.loop(); } }); thread.setName("myThread1"); thread.start(); } // 3.使用HandlerThread private void method_3() { HandlerThread handlerThread = new HandlerThread("myThread2"); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()) { public void handleMessage(Message msg) { Log.i("msg", "" + Thread.currentThread());//子线程myThread2 runOnUiThread(new Runnable() { @Override public void run() { layout.helloText .setText("而handlerThread可以直接用handlerThread.getLooper()拿到looper,可以不用管looper,可以省事"); } }); } }; handler.sendEmptyMessage(0); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: method_1(); break; case R.id.button2: method_2(); break; case R.id.button3: method_3(); break; default: break; } } }
完整demo:http://pan.baidu.com/s/1qWwTs3y
作者:chace