RxTask-快捷切換線程,告別處處建立handler

RxTask,基於線程池+handler封裝工具。今後告別處處建立handler,遠離處處建立線程沒法管理。
已遷移到Androidx

早期的版本介紹:
RxTask第一版上篇
RxTask第一版下篇
java

項目地址 個人Github 個人碼雲git

集成方式: implementation 'com.xujl:task:1.0.1'
github

初始化

//默認初始化,默認初始化後核心線程數爲cpu核心數X4
 RxExecutor.getInstance().init();
 //自定義核心線程數量進行初始化
 RxExecutor.getInstance().init(32);
 //徹底自定義工具線程池
 RxExecutor.getInstance().init(ExecutorService);
 //關閉log輸出,默認爲開啓
 RxExecutor.getInstance().setDebug(false);
複製代碼

如何使用?

場景1

子線程任務,執行完畢結果數據返回給主線程顯示
RxExecutor.getInstance()
                .executeTask(new Task<String>(){
                    @Override
                    public void run (Emitter<String> emitter) throws Exception {
                        super.run(emitter);
                        //當前爲子線程
                        //模擬子線程任務
                        Thread.sleep(1000);
                        //任務結束髮送數據到主線程
                        emitter.next("任務執行結果數據");
                    }

                    @Override
                    public void onNext (String data) {
                        super.onNext(data);
                        //當前爲主線程
                        //顯示子線程執行結果
                        textView.setText(data);
                    }
                });
複製代碼

場景2

子線程任務,不關心任務結果,只關心完成時機
RxExecutor.getInstance()
                .executeTask(new Task<String>() {
                    @Override
                    public void run (Emitter<String> emitter) throws Exception {
                        super.run(emitter);
                        //當前爲子線程
                        //模擬子線程任務
                        Thread.sleep(1000);
                        //任務結束
                    }

                    @Override
                    public void onFinished () {
                        super.onFinished();
                        //當前爲主線程
                        // 執行主線程邏輯
                    }
                });
複製代碼

場景3

單純執行一個子線程任務,不關心任務結果,也不須要在任務結束後有任何操做
RxExecutor.getInstance()
                .executeTask(new Task<String>() {
                    @Override
                    public void run (Emitter<String> emitter) throws Exception {
                        super.run(emitter);
                        //當前爲子線程
                        //模擬子線程任務
                        Thread.sleep(1000);
                        //任務結束
                    }
                });
複製代碼

場景4

執行一個普通子線程而非task
RxExecutor.getInstance()
                        .executeRunnableTask(new Runnable() {
                            @Override
                            public void run () {
                                //當前爲子線程
                                //模擬子線程任務
                                Thread.sleep(1000);
                                //任務結束
                            }
                        });
複製代碼

場景5

執行的任務綁定生命週期,界面銷燬後,再也不回調

在bindLife方法中完成綁定,生命週期結束後,onFinished和onNext將不會再回調。app

private RxLifeList mBindLife = new RxLifeList();
    private void test(){
        RxExecutor.getInstance()
                .executeTask(new Task<String>() {
                    @Override
                    public void run (Emitter<String> emitter) throws Exception {
                        super.run(emitter);
                        //當前爲子線程
                        //模擬子線程任務
                        Thread.sleep(2000);
                        //任務結束
                    }

                    @Override
                    public void onNext (String data) {
                        super.onNext(data);

                    }

                    @Override
                    public void onFinished () {
                        super.onFinished();
                        //當前爲主線程
                        // 執行主線程邏輯
                    }

                    @Override
                    public void bindLife (RxLife rxLife) {
                        super.bindLife(rxLife);
                        mBindLife.add(rxLife);
                    }
                });
    }
    @Override
    protected void onDestroy () {
        if (mBindLife != null) {
            mBindLife.onDestroy();
        }
        super.onDestroy();
    }
複製代碼

場景6

當前處於某個子線程任務中,須要主線程中顯示數據
//其餘子線程中
        new Thread(new Runnable() {
            @Override
            public void run () {
                //模擬子線程任務
                Thread.sleep(1000);
                //切換回主線程進行邏輯
                RxExecutor.getInstance()
                        .executeUiTask(new Task() {
                            @Override
                            public void onlyRunUiTask () {
                                super.onlyRunUiTask();
                                //執行主線程邏輯
                            }
                        });
            }
        }).start();
複製代碼

場景7

任務執行失敗,進行重試

使用 TaskBuilder.create().setRetryMaxCount(3)傳入task構造器便可實現重試功能,方法參數爲最大重試次數,傳入 TaskRetry.INFINITE可實現無限重試(一般不建議這麼作!)。
Task默認配置爲失敗後不重試
任務失敗後會回調onError方法並返回具體錯誤,若是沒有配置重試,進入onError的Task將結束生命週期,再也不回調onFinished或者onNext方法。ide

RxExecutor.getInstance()
                .executeTask(new Task<String>(
                        //配置失敗重試
                        TaskBuilder.create()
                                .setRetryMaxCount(3)
                ) {
                    @Override
                    public void run (Emitter<String> emitter) throws Exception {
                        super.run(emitter);
                        //當前爲子線程
                        //模擬子線程任務
                        Thread.sleep(1000);
                        //任務結束
                    }

                    @Override
                    public void onError (Exception e) {
                        super.onError(e);
                        //任務出錯
                    }

                    @Override
                    public void onFinished () {
                        super.onFinished();
                        //當前爲主線程
                        // 執行主線程邏輯
                    }
                });
複製代碼

場景8

任務組

任務組是一種比較不常見的場景,好比開啓雙線程分別寫入兩個文件到內存卡,而且兩個文件完成寫入後退出界面。這時候就可使用任務組概念進行工具

RxExecutor.getInstance()
                .executeTaskGroup(GroupTaskBuilder.create()
                        .setResultTask(new GroupResultTask() {

                            @Override
                            public void oneTaskComplete (Object tag, Object result) {
                                result("任務" + tag.toString() + "執行結束,數據爲:" + result, R.color.task_color_4);
                            }

                            @Override
                            public void allTaskComplete (HashMap<Object, Object> resultMap) {
                                StringBuilder result = new StringBuilder();
                                for (Object o : resultMap.keySet()) {
                                    result.append(o.toString());
                                    result.append(":");
                                    result.append("" + resultMap.get(o));
                                }
                                result("組任務所有完畢,數據爲:" + result.toString(), R.color.task_color_4);
                            }
                        })
                        .setGroupStrategy(GroupTaskStrategy.ALL_COMPLETE)
                        .addGroupTask(mGroupTask1)
                        .setResultTag(1)
                        .addGroupTask(mGroupTask2)
                        .setResultTag(2)
                        .addGroupTask(mGroupTask3)
                        .setResultTag(3)
                        .build());
複製代碼

GroupResultTask是用來監控任務組執行結果的,每一個任務執行完畢後會回調一次oneTaskComplete,全部任務執行完畢後會回調一次allTaskComplete,兩個方法的參數列表返回了單個任務執行的數據結果,經過配置的tag進行判斷,固然若是你不關心執行結果數據則能夠沒必要調用setResultTag給每一個任務設置tag。
任務組的執行模式有三種,經過setGroupStrategy方法進行設置(使用默認模式能夠不調用這個方法):post

/** * 默認模式 * 所有完成模式,所有任務執行完畢後 * 回調結果 * 使用此模式,若是組任務配置了失敗 * 重試,則最終回調會等待組任務重試成功 * 組任務配置了任務重試會阻塞結果回調時機 */
    public static final int ALL_COMPLETE = 0;
    /** * 錯誤退出模式 * 一個組任務發生錯誤則暫停其餘任務 * 並再也不繼續 */
    public static final int ERROR_EXIT = 1;
    /** * 錯誤忽略模式 * 一個任務發生的錯誤將會被忽略 * 其餘任務正常執行,並待其餘任務執行後 * 繼續後續任務,使用此模式會忽略任務重試功能 * 組任務配置了任務重試不會阻塞結果回調時機 */
    public static final int ERROR_IGNORE = 2;
複製代碼

須要注意的是ALL_COMPLETE和ERROR_IGNORE的阻塞區別,主要來源於子任務的重試策略對他們產生的不一樣影響。

若是你的任務組中,有一個是必要的(必須完成,不完成會影響後續邏輯),其餘是非必要的(順便執行的任務,不關心是否成功),該怎麼辦?
不用擔憂,RxTask能夠在組策略下配置單個任務的策略,好比下面的示例,任務1和3爲非核心邏輯,2爲核心邏輯,那麼只須要以下配置便可保證任務1和3失敗後對最後的任務組完成回調不產生影響。
ui

RxExecutor.getInstance()
                .executeTaskGroup(GroupTaskBuilder.create()
                        .setResultTask(new GroupResultTask() {

                            @Override
                            public void oneTaskComplete (Object tag, Object result) {
                                result("任務" + tag.toString() + "執行結束,數據爲:" + result, R.color.task_color_4);
                            }

                            @Override
                            public void allTaskComplete (HashMap<Object, Object> resultMap) {
                                StringBuilder result = new StringBuilder();
                                for (Object o : resultMap.keySet()) {
                                    result.append(o.toString());
                                    result.append(":");
                                    result.append("" + resultMap.get(o));
                                }
                                result("組任務所有完畢,數據爲:" + result.toString(), R.color.task_color_4);
                            }
                        })
                        .setGroupStrategy(GroupTaskStrategy.ALL_COMPLETE)
                        //非核心業務,能夠容許失敗
                        .addGroupTask(mGroupTask1)
                        .setStrategy(GroupTaskStrategy.ERROR_IGNORE)
                        .setResultTag(1)
                        //核心業務,必須成功才進行下一步
                        .addGroupTask(mGroupTask2)
                        .setResultTag(2)
                        //非核心業務,能夠容許失敗
                        .addGroupTask(mGroupTask3)
                        .setStrategy(GroupTaskStrategy.ERROR_IGNORE)
                        .setResultTag(3)
                        .build());
複製代碼

使用單任務策略須要注意如下幾點
首先,單任務的執行策略僅在任務組策略爲GroupTaskStrategy.ALL_COMPLETE時纔有效。
其次,任務組策略爲GroupTaskStrategy.ALL_COMPLETE且沒有配置單任務策略時,須要當心任務阻塞的處理,由於在此模式下,任何一個子任務執行失敗都會形成你的後續邏輯執行不到,因此須要考慮每一個任務失敗時的處理邏輯。子任務出錯參考前面Task任務出錯時的狀況。
最後,在activity中使用任務組時請務必綁定生命週期,以避免出現內存泄漏問題。spa

場景9

多種類型數據結果

一個子線程任務過程當中可能產生不一樣結果或者多個結果,那麼能夠採用下面的寫法(注意使用 emitter.objNext發射數據,用onObjNext接收數據),此方法能夠用來控制多種類型或者多個步驟的子線程任務,每種類型或者步驟識別使用code來進行線程

RxExecutor.getInstance()
                .executeTask(new Task<Object>() {
                    @Override
                    public void run (Emitter<Object> emitter) throws Exception {
                        super.run(emitter);
                        Thread.sleep(1000);
                        //執行結果數據類型1
                        emitter.objNext("數據1", 1);
                        Thread.sleep(1000);
                        //執行結果數據類型2
                        emitter.objNext(222, 2);
                        Thread.sleep(1000);
                        //執行結果數據類型3
                        emitter.objNext(new Bundle(), 3);
                    }

                    @Override
                    public void onObjNext (int code, Object obj) {
                        super.onObjNext(code, obj);
                        switch (code) {
                            case 1:
                                //處理數據類型1
                                break;
                            case 2:
                                //處理數據類型2
                                break;
                            case 3:
                                //處理數據類型3
                                break;
                            default:

                                break;

                        }
                    }
                });
複製代碼

場景10

經常使用子任務封裝

如下三種類型均支持綁定生命週期,綁定生命週期後,生命週期結束,將再也不回調

倒計時
RxExecutor.getInstance()
                .executeTask(new RxHelper.CountDownTask(60*1000,1000) {
                    @Override
                    public void count (long time) {
                        
                    }
                });
複製代碼
延時任務
RxExecutor.getInstance()
                .executeTask(new RxHelper.DelayTask(60*1000) {

                    @Override
                    public void timeOver () {
                        
                    }
                });
複製代碼
循環任務

-1表示無限循環

RxExecutor.getInstance()
                .executeTask(new RxHelper.RecycleTask(1000,-1) {
                    @Override
                    public void count (int count) {
                        
                    }
                });
複製代碼
相關文章
相關標籤/搜索