幫助Android應用做初始化調度的庫:Init

jopen 9年前發布 | 10K 次閱讀 Init Android開發 移動開發

Init幫助Android應用調度復雜的任務流(如應用初始化流程),如下一節圖示的那種任務流,處理類型、優先級、多進程(像是每個進程都會執行application的onCreate),任務依賴,提高應用啟動效率。

盡管Init設計的初衷是為了應用(application)初始化,但并不局限于此,它可以于應用在任何復雜的初始化流程。

Init不依賴于任何第三方庫,使用Java concurrent并部分依賴于Android SDK(Context, Log),所以理論上也可以在簡單修改后直接用于Java工程。

How

初始化流程被抽象為flow、wave和task。

flow

flow是一個粗粒度概念,通常一個應用只有一個flow,但某些情況下我們可能擁有多個flow,像是patch flow,broadcast flow,fake UI flow等等,可以把它們都交給Init處理。

每個wave只有在上一wave的所有阻塞task完成后才能開始,而所有屬于該wave的task會一起開始執行(除非被賦予了delay)。

至于task,在本庫中屬于原子性操作,他們可以被分為2大類型

  1. 阻塞task,即圖中的藍色任務。
  2. 異步task,又可以被分為
    • 完全異步或者橫跨若干個wave后才需要阻塞,像圖中的綠色task。
    • 異步鏈,像圖中的紅色task。

使用

dependencies {
    compile 'cn.zhaiyifan:init:1.0.1' }
public class DemoApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Init需要應用context來獲得進程相關信息
        Init.init(this);
        // 可以使用自定義的log離開輸出Init的Log,logProxy需要實現cn.zhaiyifan.appinit.ILog接口
        // Init.init(this, logProxy)

        // 默認Task,延遲0,且阻塞下一波task的執行,參數字符串可以用來追蹤任務執行狀態
        Task task1 = new Task("task1") {

            @Override
            protected void start() {
                doSomeThing();
            }

            // 僅在返回true的時候才會在對應進程執行
            @Override
            public boolean runOnProcess(String processName) {
                return processName.equals("cn.zhaiyifan.demo");
            }
        };

        // 創建一個task,非阻塞,且延時300毫秒執行
        Task task2 = new Task("task2", false, 300) {

            @Override
            protected void start() {
                doSomeThing();
            }
        };

        // 類似地,創建更多task,如task3、task4等等

        // 創建一個有名flow
        Flow flow = new Flow("flow");
        // 往flow添加剛才創建的task, 第一個參數是wave序號,會從小到大執行每個wave的task
        flow.addTask(1, task1).addTask(1, task2).addTask(2, task3).addTask(2, task4);
        // 啟動flow,開始初始化
        Init.start(flow);
    }

看一下log,可以發現原來一個串行執行需要2700毫秒的任務,在我們的安排下,現在只需要1307毫秒就可以結束。

10-04 18:53:54.789 646-666/cn.zhaiyifan.init I/Task: task2 runs 500
10-04 18:53:55.289 646-665/cn.zhaiyifan.init I/Task: task1 runs 1000
10-04 18:53:55.591 646-741/cn.zhaiyifan.init I/Task: task3 runs 300
10-04 18:53:55.592 646-646/cn.zhaiyifan.init I/Flow: flow runs 1307
10-04 18:53:55.990 646-740/cn.zhaiyifan.init I/Task: task4 runs 700
10-04 18:53:56.191 646-783/cn.zhaiyifan.init I/Task: task5 runs 200

Useful api:

// 設置線程池大小
Init.setThreadPoolSize(...)

// 取消一個已經開始的flow
Init.cancel(...)

// 獲得flow狀態
Init.getFlowStatus(...)

// 獲得特定的task狀態
flow.getTaskStatus(taskName)

// 設置超時限制
flow.setTimeout(5000)

等等

更多詳情請見demo工程。

為什么需要Init

想象一下我們是怎么去初始化一個大型應用像是支付寶、QQ、微信、空間等的,我們會面對像是下面這種代碼:

public class XXXApplication {

    // for multi-dex apps
    @Override
    protected void attachBaseContext(Context base) {
        // log init
        ...
        // eventbus init...
        ...
        // global variables init
        ...
        // process related
        String processName = ...
        boolean isMainProcess = ...
        ProcessInit.attachBaseContext(this, processName, isMainProcess);
    }

    @Override
    protected void onCreate() {
        // process related
        String processName = ...
        boolean isMainProcess = ...

        // CrashHandler, SafeMode, plugin, image manager, database, download, update, etc init

        ProcessInit.onCreate(this, processName, isMainProcess);
    }

}

public class ProcessInit {
    ...
    public static void onCreate(Application application, boolean isMainProcess, String processName) {
        if (isMainProcess) {

        }
    } else if (processName.contains(PUSH_PROCESS_SUFFIX)) {
        ...
    } else if (processName.contains(WEB_PROCESS_SUFFIX)) {
        ...
    } else if (processName.contains(MUSIC_PROCESS_SUFFIX)) {
        ...
    } else {
        ...
    }
    ...
}

你看到了當一個應用越來越大以后初始化能是一件多么復雜的事情,有些操作必須在另一個之后,而又有一些可以并行執行,又有的操作又需要在一個異步操作完成后才能執行......于是我們就得把每個獨立的操作進行修改,有的改成異步,有的則阻塞在另一個操作后,使得代碼雜亂且難以維護。

怎么可以使它變得簡單呢?Init就是來幫助你做這個事的。

項目主頁:http://www.baiduhome.net/lib/view/home/1444118102323

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!