标签:
之前说过了,Android不允许主线程(MainThread)外的线程(WorkerThread)去修改UI组件,但是又不能把所有的更新UI的操作都放在主线程中去(会造成ANR),那么只能单独启动一个子线程(WorkerThread)去处理,处理完成之后,将结果通知给UI主线程,子线程和主线程的通信就用到了Handler。
先看一下他们的职责:
Handler——处理者,负责发送以及处理Message。
MessageQueue——消息队列,用来存放Handler发送过来的消息,采用FIFO(first in first out)规则将Message以链表的方式串联起来的,等待Looper的抽取。
Looper——消息泵,不断的从消息队列中取出消息并回传给Handler
1. Handler对象调用obtainMessage()方法获取Message对象
2. 调用sendMessage(Message msg)方法将消息发送到消息队列(MessageQueue)中
3. Looper循环这从消息队列中取出msg
4. 调用Handler对象的handleMessage(Message msg)方法,将取出的msg传给Handler
Handler将消息传到队列,Looper从队列中拿到消息,然后又传给了Handler,这似乎是一个无用功,我们通过代码来看一下。
package cn.lixyz.handlertest; import android.app.Activity; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; /** * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。 */ public class MainActivity extends Activity { private Button button; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); handler = new MyHandler(); button.setOnClickListener(new ButtonOnClickListener()); } class ButtonOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { Thread t = new ChangePicThread(); t.start(); } } class ChangePicThread extends Thread { @Override public void run() { super.run(); try { Thread.sleep(1 * 1000); Log.d("TTTTT", "---->" + Thread.currentThread().getName()); Message msg = handler.obtainMessage(); msg.what = 100; handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } } //创建内部类,继承Handler,用来创建Handle对象 class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("TTTTT", "====>" + Thread.currentThread().getName()); int i = msg.what; Log.d("TTTTT", "message=" + i); } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="30dp" android:text="sendMessage" /> </LinearLayout>
点击按钮,查看log
09-16 10:55:12.064 12614-12669/cn.lixyz.handlertest D/TTTTT﹕ ---->Thread-213
09-16 10:55:12.064 12614-12614/cn.lixyz.handlertest D/TTTTT﹕ ====>main
09-16 10:55:12.064 12614-12614/cn.lixyz.handlertest D/TTTTT﹕ message=100
可以看到,ChangePicThread的线程名是Thread-213,MyHandler的线程名是main,那message也传递过来了,那我们不就可以在线程中将所需要处理的内容处理好,将结果传给Handler,由Handler去修改UI么
点击按钮,开始播放幻灯片。
package cn.lixyz.handlertest; import android.app.Activity; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.ImageView; /** * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。 */ public class MainActivity extends Activity { private ImageView imageView; private Button button; private Handler handler; private int[] images = {R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6,}; private int index = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); imageView = (ImageView) findViewById(R.id.imageView); handler = new MyHandler(); button.setOnClickListener(new ButtonOnClickListener()); } //创建内部类,实现OnClickListener接口,用于注册监听按钮开始事件 class ButtonOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { Thread t = new ChangePicThread(); t.start(); } } //创建内部类,用户执行2s变换幻灯片 class ChangePicThread extends Thread { @Override public void run() { super.run(); try { while (true) { Object obj = new Object(); synchronized (obj) { Message msg = handler.obtainMessage(); msg.obj = index; handler.sendMessage(msg); index++; Thread.sleep(2 * 1000); if (index >= images.length ) { index = 0; } } } } catch (InterruptedException e) { e.printStackTrace(); } } } // class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); int i = (int) msg.obj; BitmapDrawable bd = (BitmapDrawable) imageView.getDrawable(); if (bd != null && !bd.getBitmap().isRecycled()) { bd.getBitmap().recycle(); } imageView.setImageResource(images[i]); } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="30dp" android:text="点击播放" /> </LinearLayout>
Android笔记(三十) Android中的异步更新(二) Handler
标签:
原文地址:http://www.cnblogs.com/xs104/p/4814858.html