Android中的Handler使用方式
来源:互联网 发布:js需要做保护层吗 编辑:程序博客网 时间:2024/06/05 14:12
一、什么是Handler
Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制。每个Hanlder都关联了一个线程,每个线程内部都维护
了一个消息队列MessageQueue,这样Handler实际上也就关联了一个消息队列。可以通过Handler将Message和Runnable对象发
送到该Handler所关联线程的MessageQueue(消息队列)中,然后该消息队列一直在循环拿出一个Message,对其进行处理,处
理完之后拿出下一个Message,继续进行处理,周而复始。当创建一个Handler的时候,该Handler就绑定了当前创建Hanlder的线
程。从这时起,该Hanlder就可以发送Message和Runnable对象到该Handler对应的消息队列中,当从MessageQueue取出某个
Message时,会让Handler对其进行处理。
二、Handler作用
Handler可以用来在多线程间进行通信,在另一个线程中去更新UI线程中的UI控件只是Handler使用中的一种典型案例,除此之外,
Handler可以做很多其他的事情。每个Handler都绑定了一个线程,假设存在两个线程ThreadA和ThreadB,并且HandlerA绑定了
ThreadA,在ThreadB中的代码执行到某处时,出于某些原因,我们需要让ThreadA执行某些代码,此时我们就可以使用
Handler,我们可以在ThreadB中向HandlerA中加入某些信息以告知ThreadA中该做某些处理了。由此可以看出,Handler是
Thread的代言人,是多线程之间通信的桥梁,通过Handler,我们可以在一个线程中控制另一个线程去做某事。
三、主线程中的Handler
下面的Handler是主线程中的Handler,因为其是在主线程中创建的,所以默认就是和主线程进行绑定的,通过一个延时的POST方法来进行UI的循环更新。
public class MainActivity extends AppCompatActivity { private Handler handler = new Handler(); private int images[] = new int[]{R.drawable.im1, R.drawable.im2, R.drawable.im3}; private int index = 0; private MyRunnable myRunnable = new MyRunnable(); private ImageView im_debug; class MyRunnable implements Runnable{ @Override public void run() { index++; index = index % 3; im_debug.setImageResource(images[index]); handler.postDelayed(myRunnable, 1000); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); im_debug = (ImageView) findViewById(R.id.im_debug); handler.postDelayed(myRunnable, 1000); } }
四、两种Handler发消息
如下是Handler的两种绑定方式,一个和主线程进行绑定,一个和子线程进行绑定,这两个分别向主线程的Handler和子线程的
Handler发消息就可以得到得到其线程的ID,并且子线程中建立Looper
public class SecondActivity extends Activity { private MyThread thread; //默认是在主线程中执行 public Handler uiHandler = new Handler(){ @Override public void handleMessage(Message msg) { System.out.print("UI-----"+Thread.currentThread()); } }; //在子线程中执行 class MyThread extends Thread{ public Handler hander; public void run(){ Looper.prepare(); hander = new Handler(){ @Override public void handleMessage(Message msg) { System.out.print("CurrentID = "+Thread.currentThread()); } }; Looper.loop(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("hello Handler"); setContentView(tv); thread = new MyThread(); thread.start(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //向子线程发消息 thread.hander.sendEmptyMessage(1); //向主线程发消息 uiHandler.sendEmptyMessage(1); } }
五、HandlerThread使用
HandlerThread建立的线程是在子线程中的,建立子线程的Handler的时候要绑定一个Looper
public class ThreeActivity extends Activity { private HandlerThread thread; private Handler handler; private static final String TAG = "ThreeActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("Handler Thread Handler"); setContentView(tv); //HandlerThread中使用了同步机制了 thread = new HandlerThread("handlerThread"); thread.start(); //如果looper为空,就处于等待的状态,直到Handler可以拿到looper对象 //这个是子线程的Handler handler = new Handler(thread.getLooper()){ @Override public void handleMessage(Message msg) { System.out.print("当前线程:"+Thread.currentThread()); Log.i(TAG, "当前线程"+Thread.currentThread()); } }; handler.sendEmptyMessage(1); }}
六、Handler更新UI
Handler提供了两种方式解决我们在本文一开始遇到的问题(在一个新线程中更新主线程中的UI控件),一种是通过post方法,一
种是调用sendMessage方法。
public class FiveActivity extends Activity { private TextView tv_five; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { tv_five.setText("OK了方法2"); } }; public void handler1(){ //这个是第一种方式来更新UI //本质上也是发送message handler.post(new Runnable() { @Override public void run() { tv_five.setText("OK了方法1"); } }); } public void handler2(){ handler.sendEmptyMessage(1); } public void handler3(){ //内部还是通过UI机制 runOnUiThread(new Runnable() { @Override public void run() { tv_five.setText("OK了方法3"); } }); } public void handler4(){ // tv_five.post(new Runnable() { @Override public void run() { tv_five.setText("OK了方法4"); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); tv_five = (TextView) findViewById(R.id.tv_five); new Thread(){ @Override public void run() { try { Thread.sleep(2000); //分别在此处调用不同的更新UI的方法 handler4(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); }}
其实最常用的还是那两种方式,虽然Message的构造函数式public的,我们还可以通过Message.obtain()或
Handler.obtainMessage()来获得一个Message对象(Handler.obtainMessage()内部其实调用了Message.obtain())。
详细的介绍请参考下面两篇文章,写的很好:
http://blog.csdn.net/iispring/article/details/47115879
http://blog.csdn.net/iispring/article/details/47180325
- Android中的Handler使用方式
- Android中的Handler的使用
- Android中Handler的进阶使用方式
- Android Handler的使用方式和注意事项
- 使用android中的handler延迟执行方法
- Android中的Timer和Handler的使用
- Handler---Handler异步方式详解及其使用
- Android 定时器的实现方式(TimerTask、Handler)及 Handler使用解析
- Android 定时器的实现方式(TimerTask、Handler)及 Handler使用解析
- Android中的Handler
- android中的handler例
- Android中的Handler总结
- Android中的Handler总结
- Android中的handler
- Android中的Handler总结
- Android中的Handler机制
- Android中的Handler总结
- Android中的Handler总结
- eclipse中启动项目时出现java.lang.OutOfMemoryError错误
- json-lib 之jsonConfig详细使用(转载写的不错)
- Java 泛型
- app:showAsAction 和android:showAsAction的区别
- iOS 证书
- Android中的Handler使用方式
- 彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)
- json_value.asm: No such file or directory
- ZigZag Conversion
- 浅谈Linux目录文件权限管理
- jQuery的attr()属性
- ACM日记_17.3.14——*最大公约数*与*最小公倍数*
- 虚拟化应用交付解决方案【ANS SOLUTIONS】
- 通过setAllowNonStringKeys解决java.lang.ClassCastException: JSON keys must be strings