用子线程更新UI的集中方式

1. Java代码

package com.bwf.a8_ui_operation;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
 *     一、子线程执行耗时操作,间接更新UI的第一种方式之发消息更新UI的基本流程
 *         1. 子线程中执行耗时操作和发送消息
 *             a. 定义一个子线程类(实现Runnable或者继承Thread)
 *             b. 实现run方法
 *                 做相关的耗时操作
 *                 发送消息
 *         2. 在handler中处理消息
 *             a. 定义个类来继承自Handler
 *             b. 覆盖其handleMessage方法,在此方法中实现更新UI的操作
 *         3. 在UI线程中创建Handler对象和启动子线程
 *             a. 创建Handler对象
 *             b. 创建线程对象
 *             c. 启动该线程
 * 
 * 二、子线程执行耗时操作,间接更新UI的第二种方式之Activity的runOnUiThread的方式
 *         runOnUiThread(Runnable r);
 *         该方法内部做了判断当前线程是否为UI线程的操作
 *         public final void runOnUiThread(Runnable action) {
            if (Thread.currentThread() != mUiThread) {
                mHandler.post(action);        // 不是UI线程则将该action添加到mHandler所在的
                                                UI线程的消息队列中
            } else {
                action.run();                // 是UI线程,则直接执行
            }
        }
 * 
 * 三、子线程执行耗时操作,间接更新UI的第三种方式之Handler的post方式
 *         handler.post(Runnable r);
 *         该方法内部实际上是发送一个延迟的消息给该线程的Handler处理,
 *         如果是更新UI,则这个Handler对象必须创建在UI线程中
 *         public final boolean post(Runnable r)
        {
           return  sendMessageDelayed(getPostMessage(r), 0);
        }
        
        几种发送消息的函数内部的关联
        public final boolean sendMessage(Message msg)
        {
            return sendMessageDelayed(msg, 0);
        }
        
        sendMessage内部调用了sendMessageDelayed延迟0毫秒
        
        public final boolean sendMessageDelayed(Message msg, long delayMillis)
        {
            if (delayMillis < 0) {
                delayMillis = 0;
            }
            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
        }
        
        sendMessageDelayed内部调用了sendMessageAtTime当前时间加上延迟的毫秒数等于指定时间发送消息
        
        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
        }
        
        该方法内部将消息对象加入了消息队列
 * */
public class MainActivity extends Activity {
    TextView tv;
    int count = 20;
    Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = (TextView) findViewById(R.id.tv);
        handler = new Handler();
        
        Button btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        while(count>=0){
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            
                            // 通过runOnUiThread更新UI
                            /*runOnUiThread(new Runnable() {
                                
                                @Override
                                public void run() {
                                    if(count>0){
                                        tv.setText(count+"");
                                    } else{
                                        tv.setText("计时结束");
                                    }
                                    count--;
                                }
                            });*/
                            
                            // 通过UIThread中创建的Handler对象,将动作Runnable对象给加入到UI线程的消息队列
                            handler.post(new Runnable() {
                                
                                @Override
                                public void run() {
                                    if(count>0){
                                        tv.setText(count+"");
                                    } else{
                                        tv.setText("计时结束");
                                    }
                                    count--;
                                }
                            });
                        }
                    }
                }).start();
            }
        });
    }
}

 

posted on 2015-09-19 13:05  敬的男人  阅读(82)  评论(0)    收藏  举报