Android中Handler的意义和用法

来源:互联网 发布:淘宝达人入口网址 编辑:程序博客网 时间:2024/05/22 03:20

Handler用于线程间的通信,本文分析Handler、Looper、MessageQueue等的原理及Handler和BroadcastReceiver的差异。

线程A创建Looper及MessageQueue,创建Handler;在线程B创建消息,用Handler将消息PUSH给由Looper管理的MessageQueue;线程A通过Looper循环查询MessageQueue,发现消息则POP给Handler处理。

1、示例分析

1) MainActivity.java

public class MainActivity extends Activity {private static final String TAG = MainActivity.class.getSimpleName();public static final int MSG_FIRST = 0x01;public static final int MSG_SECOND = 0x02;public static final int MSG_THIRD = 0x03;public static final int MSG_FOURTH = 0x04;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}Handler mHandler = new Handler(){@Overridepublic void dispatchMessage(Message msg) {Log.i(TAG, "dispatchMessage-"+msg.what);//super.dispatchMessage(msg);if(handler_sub!=null)handler_sub.dispatchMessage(msg);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch(msg.what){case MSG_FIRST:Log.i(TAG, "MSG_FIRST");break;case MSG_SECOND:Log.i(TAG, "MSG_SECOND");break;}}};private class MyThread extends Thread{int mId = 0;public MyThread(int id){mId = id;}@Overridepublic void run() {super.run();//global message poolswitch(mId){case 0:mHandler.obtainMessage(MSG_FIRST).sendToTarget();break;case 1:Message msg = new Message();msg.what = MSG_SECOND;mHandler.sendMessageDelayed(msg, 5000L);//mHandler.sendMessageAtTime(msg, SystemClock.uptimeMillis()+5000L);//mHandler.sendMessageAtFrontOfQueue(msg);//mHandler.sendMessage(msg);break;case 2:Message.obtain(mHandler, MSG_THIRD).sendToTarget();//Message.obtain(mHandler, MSG_THIRD, 1, 2, null).sendToTarget();}}}public void onClick(View v){switch(v.getId()){case R.id.btn:MyThread myThread = new MyThread(0);myThread.start();break;case R.id.btn2:MyThread myThread1 = new MyThread(1);myThread1.start();break;case R.id.btn3:MyThread myThread2 = new MyThread(2);myThread2.start();break;case R.id.btn4:MyThread2 mt = new MyThread2();mt.start();}}Handler handler_sub;private class MyThread2 extends Thread{@Overridepublic void run() {super.run();Looper.prepare();mHandler.postDelayed(new Runnable() {@Overridepublic void run() {TextView tv = (TextView) findViewById(R.id.txt);tv.setText("less popular");}}, 3000L);handler_sub = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);Log.i(TAG, "handleMessage-"+Thread.currentThread().getName()+"|"+msg.what);}};Looper.loop();Looper.myLooper().quitSafely();}}}
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    xmlns:android="http://schemas.android.com/apk/res/android">    <Button         android:id="@+id/btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="send"/>    <Button         android:id="@+id/btn2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="send2"/>    <Button         android:id="@+id/btn3"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="send3"/>    <Button         android:id="@+id/btn4"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="send4"/>    <TextView         android:id="@+id/txt"        android:layout_width="match_parent"        android:layout_height="wrap_content"/></LinearLayout>

2、Handler和BroadcastReceiver的比较

差异:发消息需要Handler引用,而发广播只需提供ACTION;发前后Message和Object还是同一个对象,Intent和Bundle已是另一个对象。

1) MainActivity.java

public class MainActivity extends Activity {private static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.i(TAG, "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);IntentFilter filter = new IntentFilter();filter.addAction(MyBroadcastReceiver.ACTION_RABBIT);registerReceiver(receiver, filter);}protected void onDestroy() {Log.i(TAG, "onDestroy");super.onDestroy();unregisterReceiver(receiver);//注销所有ACTION};MyBroadcastReceiver receiver = new MyBroadcastReceiver();Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0://Message和Person对象不变Log.w(TAG, "handleMessage-msg:"+msg.hashCode());Log.w(TAG, "handleMessage-Person:"+msg.obj.hashCode());break;default:break;}};};public void onClick(View v){switch (v.getId()) {case R.id.btn:Person p = new Person();p.setName("talent");p.setAge(21);Log.w(TAG, "onClick-Person:"+p.hashCode());Message msg = mHandler.obtainMessage(0, p);Log.w(TAG, "onClick-msg:"+msg.hashCode());msg.sendToTarget();break;case R.id.btn_broadcast://Intent和Bundle均是Parcelable、Cloneable的子类Intent intent = new Intent();intent.setAction(MyBroadcastReceiver.ACTION_RABBIT);Bundle bundle = new Bundle();Log.w(TAG, "onClick-Bundle:"+bundle.hashCode());Log.w(TAG, "onClick-Intent:"+intent.hashCode());bundle.putBoolean("ready", true);intent.putExtras(bundle);//intent.removeExtra(String);sendBroadcast(intent);break;default:break;}}}
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    xmlns:android="http://schemas.android.com/apk/res/android">    <Button         android:id="@+id/btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="tap me"/>    <Button         android:id="@+id/btn_broadcast"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="onClick"        android:text="send broadcast"/></LinearLayout>
3) Person.java
public class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
4) MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {private static final String TAG = MyBroadcastReceiver.class.getSimpleName();public static final String ACTION_RABBIT = "action.rabbit";@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();//set/getif(ACTION_RABBIT.equals(action)){Bundle bundle = intent.getExtras();//put/get//传过来的Intent和Bundle对象均已变Log.w(TAG, "onReceive-Bundle:"+bundle.hashCode());Log.w(TAG, "onReceive-intent:"+intent.hashCode());}}}


0 0