Android设置非UI线程不能更新UI,但是很多情况下需要在其他线程中去加载一些耗时的操作,这个时候就得需要异步处理.Android提供了Handler的消息处理机制,很好的帮我们解决了这个问题。
Handler意为处理者,整套Handler机制分为四个部分
1 Handler 消息处理者也是发送者(可以理解为生产产品的工人)
2 Message 消息 (可以理解为工人生产的产品)
3 MessageQueue 消息队列 (可以理解为传送带)
4 Looper (可以理解为传送带的动力)
looper不断地调用函数 loop 用消息队列MessageQueue中取出消息并且返还给handler对象,handler对象调用自己的handlermessage函数来处理;
一个looper中只有一个MessageQueue队列。每当Handler发送一个消息后,message对象进入messagequeue队列,这个时候looper根据队列的顺序不断地从队列中取出消息,然后返还给handler对象,这个时候handler对象处理自己的逻辑。
这样很好避免了多线程更新UI引发UI线程堵塞。
同时,更新UI有四种方式
1 handler的sendmessage方法
private void test1(){ Message message=handler.obtainMessage(); message.obj="handler发送更新信息"; handler.sendMessage(message); } 2 handler的post方法,传入一个runnale参数 private void test2(){ handler.post(new Runnable() { @Override public void run() { textView.setText("handler post更新信息"); } }); } 3 runOnUiTherad方法 private void test3(){ runOnUiThread(new Runnable() { @Override public void run() { textView.setText("runOnUiTherad 更新信息"); } }); } 4控件自身的post方法 private void test4(){ textView.post(new Runnable() { @Override public void run() { textView.setText("txtview post 更新信息"); } }); }
线程之间还可以通信,在线程中通过调用其他线程的handler对象的sendmessage方法可以调用
private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { Log.i("test", "main线程收到消息:"+ msg.obj); Message message=handler1.obtainMessage(); message.obj="此为主线程发送给handler线程的消息"; handler1.sendMessage(message); } }; handler1 =new Handler(handlerThread.getLooper()){ @Override public void handleMessage(Message msg) { Log.i("test", "handler线程收到消息:"+ msg.obj); Message message=handler1.obtainMessage(); message.obj="此为handler线程发送给主线程的消息"; handler.sendMessage(message); // Log.i("test", "handler线程收到消息:"+ msg.obj); } }; 如果要使一个线程成为handler线程,那么在他的run方法中调用looper的Looper.prepare()函数 此时创建一个loop 然后在末尾调用looper.loop()方法就开启了一个handler线程