Android 子线程异步更新 UI 线程框架 Handler 模版

前言

最新利用安卓开发一个扫描银行卡号码的程序,识别过程包括了多个步骤,比较费时,需要放到后台线程去处理,不然就阻塞主线程延迟响应了,这时在增加一个进度条就完美了。后来发现 Handler 十分好用,通过 FutuerTask 反馈识别任务是否完成,未完成就由 Handler sendMessage 到 ui 线程去更新 ProgressBar 进度条状态,这里设计了一个接口类和一个线程类,适合完成耗时并需要更新 ui 主线程的工作。

  1. 这里以更新进度条 progressbar 为例,代码如下

接口类 ProgressWork

import java.util.concurrent.Future;

public interface ProgressWork<V> {

    /**
     * the work should be take into this method
     * @return future work
     */
    Future<V> doInBackground();

    /**
     * the worker would get progress from this method
     * @return
     */
    int updateProgress(); // 注意这里,这里是获取中间更新的信息,
                          //比如进度条的进度,可根据自己需要修改

    /**
     * the caller should implement this method to get the result</br>
     * showing on the ui view
     * @param result
     */
    void callBackResult(V result);
}

子线程类 ProgressAsyncWork

import java.util.concurrent.Future;

public class ProgressAsyncWork<V> extends Thread{

    ProgressWork progressWork;

    /**
     * offer by main thread,
     * postHandler would submit message of the progress in this class
     */
    Handler postHandler;

    /**
     * offer by the caller
     * need to overwrite doInBackground() function
     */
    Future<V> task;

    /**
     * the result returning from FutureTask
     */
    private V result;

    public ProgressAsyncWork(ProgressWork progressWork, 
                                    Handler postHandler) {
        this.progressWork = progressWork;
        this.postHandler = postHandler;
    }

    public V getResult() {
        return result;
    }

    @Override
    public void run() {
        // get the work thread doing in background
        task = progressWork.doInBackground();
        work();
    }

    private void work() {
        do {
            Message msg = postHandler.obtainMessage();
            if (task.isDone()) {
                // set result
                try {
                    result = task.get();
                    // callback when the work done
                    progressWork.callBackResult(result);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    break;
                }
            }
            msg.arg1 = progressWork.updateProgress();
            postHandler.sendMessage(msg);
            CommonUtils.info("progress: " + msg.arg1);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (true);
    }
}

2. 上面的代码直接可以复制到项目里就可以了,下面看看如何使用,下面的 work 放在 Activity 中

如何使用:

public void work() {
        final FutureTask<String> task;
        ProgressWork<String> progressWork;
        // set bar visible
        mProgressBar.setVisibility(View.VISIBLE);
        // new a FutureTask
        new Thread(task = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                // start work
                String error = "error Message";
                try {
                    // do your work here
                    // 耗时操作
                } catch (Exception e) {
                    e.printStackTrace();
                    return error;
                }
                return error;
            }
        })).start();

        final Handler postHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                mProgressBar.setProgress(msg.arg1);
                if (msg.arg1 >= 100 || task.isDone()) {
                    mProgressBar.setVisibility(View.GONE);
                    TextView mTextMessage = 
                         (TextView) findViewById(R.id.message_scan);
                    // 设置文本信息显示最终耗时任务的结果
                    mTextMessage.setText((String)msg.obj);
                }
            }
        };
        progressWork = new ProgressWork<String>() {
            @Override
            public Future<String> doInBackground() {
                return task;
            }
            @Override
            public int updateProgress() {
                return getProgress(); // 该方法自己实现,返回进度条的进度
            }
            @Override
            public void callBackResult(String result) {
                Message msg = postHandler.obtainMessage();
                msg.obj = result;
                postHandler.sendMessage(msg);
            }
        };

        // begin work the progressbar
        new ProgressAsyncWork<String>(progressWork, postHandler).start();
    }

以上就是这么多,如有问题请反馈哦 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章