android-----在子线程中更新UI操作的方法

来源:互联网 发布:淘宝店铺链接转换微信 编辑:程序博客网 时间:2024/05/16 01:20

      大家都知道android是不允许在子线程中更新UI操作的,所有更新操作都应该在主线程中完成,因而有了异步消息处理机制,具体源码分析见android-----Handler消息处理机制那么除了通过sendMessage以及handleMessage还有哪些方法可以在子线程中书写更新UI操作的代码呢?

      (1)通过Handler的post方法;

      (2)通过View的post方法;

      (3)通过Activity的runOnUiThread方法;

(1)通过Handler的post方法

 public final boolean post(Runnable r)    {       return  sendMessageDelayed(getPostMessage(r), 0);    }
可以看到post方法实际上调用的是sendMessageDelayed方法,这个方法的第一个参数是一个Message对象,通过getPostMessage方法将当前的Runnable对象封装成一个Message对象:

 private static Message getPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }
也就是会把Mesasge的callback属性设置为Runnable对象,而sendMessageDelayed会调用sendMessageAtTime方法,该方法会调用enqueueMessage方法将当前对象加入到消息队列中去

当我们的消息队列采用死循环进行消息处理的时候,首先会调用dispatchMessage方法,这个方法的源码:

public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg);        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }
首先会查看当前Message的callback属性是否为null,因为刚刚在post的时候已经设置该callback属性,所以不为null,那么会执行handleCallback方法,该方法的源码:

private static void handleCallback(Message message) {        message.callback.run();    }
很简单,就是直接执行当前线程而已啦!

我们来一个实例:

该实例通过点击界面上的按钮,为ImageView设置一张显示图来模拟更新界面:

public class MainActivity extends Activity {public Button mButton = null;public ImageView mImageView = null;public Handler mHandler = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mButton = (Button)findViewById(R.id.button);mImageView = (ImageView)findViewById(R.id.imageView);mHandler = new Handler();mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {new Thread(){public void run() {mHandler.post(new Runnable() {@Overridepublic void run() {//更新UI的具体操作(我们以加载一张图片到ImageView为例进行)mImageView.setBackgroundResource(R.drawable.ic_launcher);}});};}.start();}});}}

(2)通过View的post方法

首先先去View中查看此post方法:

 public boolean post(Runnable action) {        final AttachInfo attachInfo = mAttachInfo;        if (attachInfo != null) {            return attachInfo.mHandler.post(action);        }        // Assume that post will succeed later        ViewRootImpl.getRunQueue().post(action);        return true;    }
很明显第4行我们发现其实实际上View中的post方法本质上还是调用的Handler的post方法

(3)通过Activity的runOnUiThread方法

再来看看Activity的runOnUiThread方法:

public final void runOnUiThread(Runnable action) {        if (Thread.currentThread() != mUiThread) {            mHandler.post(action);        } else {            action.run();        }    }
那么很简单的一点,第2行首先判断当前线程是不是可以更新UI操作的主线程,如果不是的话,第3行同样也是调用的Handler的post方法,如果是主线程的话,则直接执行当前线程就可以啦!

0 0
原创粉丝点击