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();
    }

以上就是這麼多,如有問題請反饋哦 

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