Android 中几种更新UI界面的方法

android 更新UI的几种方法

根据之前的项目经验,以及在网上看到的一些技术文章,将UI更新的几种方法在此做个总结:(补充一点,不要混淆了Runnable和Thread,Runnable只是个单纯的任务,只是启动这个任务需要线程来驱动,而这个线程可以是主线程,也可以是子线程。认清这点非常重要)

1. 利用Android Handler机制和message消息传递

我们知道 , Android Handler机制主要用作线程之间的通信,为了易于理解,我们暂不考虑每个线程的Looper问题。UI更新一般是在主线程中完成的,而Handler就是定义在主线程中,然后通过在Handler构造方法中重写HandlerMessage()方法,来处理有其他线程(子线程)传递过来的消息,从而达到更新UI的目的。相应的,在其他线程(子线程)中,我们通过SendMessage(message)方法来传递消息。

//主线程中
        private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 0:       //更新未消费订单的数量
                int[] count = (int[]) msg.obj;
                //显示数据
                tv_unconsumptionSum.setText(count[0] + "");
                tv_consumptionSum.setText(count[1] + "");
                break;

            default:
                break;
            }
        }
    };

    //...
//子线程代码
//未消费订单 和已消费订单刷新 handler 机制  
new Thread(){
    public void run() {
    //step1 获取数据
    MyUser myUser = MyUser.getCurrentUser(MainActivity.this,MyUser.class);
    int count[] = {0,0};  //未消费菜单 和 已消费菜单
    if(myUser.getmUnconsumptionOrder() != null){
        count[0] = myUser.getmUnconsumptionOrder().size();
                            }
    if(myUser.getmConsumptionOrder() != null){
        count[1] = myUser.getmConsumptionOrder().size();
                            }
        Message message = new Message();
        message.what = 0;
        message.obj = count;
        mHandler.sendMessage(message);
                        }
                    }.start();

2.利用Android Handler机制和post

这个比较容易理解,也是UI更新常用的方法。 在一个新建的线程中进行更新界面的操作,然后在主线程中利用mHandler.post(Runnable runnable)来达到更新界面的目的,其中mHandler是在主线程中定义的。

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
            //相关数据处理
            //...
           //通知listview刷新数据
            listViewRestarant.reflashComplete();
            }
        }, 1000);

通过查找源码知道post方法和postDelay方法和message的关系

    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

    public final boolean postDelayed(Runnable r, long delayMillis)
    {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }

所以用主线程中的handler来post其实也就是在执行sendMessage方法,其中getPostMessage方法的源代码如下:

    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }

而obtain()方法则如下:从消息池中获取Message

    /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

那么消息池中的消息什么时侯会增加,通过源码查找到了recycleUnchecked()—>recycle(),是的,没错就是在这里消息被回收,这让我分分钟想到了JAVA的GC机制。跟踪到这儿我就暂停了,下次再补充,但是由于该方法是public 类型的,而且Message类中没有调用,所以推测这个方法和Looper或者Handler有关。

3.以上两种方法都是利用Handler机制在主线程中更新界面。现在讲一种子线程中更新界面的方法 —— 通过runOnUiThread()方法来实现

    class MyThread extends Thread{
        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            //数据处理
            //...
            runOnUiThread(new new Runnable() {
                public void run() {
                    //刷新界面
                    list.add(dog);
                    adapter.notifyDataSetChanged();
                }
                }
            })
        }

以上就是相关的UI更新常用方法,第一次写CSDN总结,自勉,不足之处还望指出

你可能感兴趣的:(java,andorid)