{"id":18939452,"url":"https://github.com/markzhai/init","last_synced_at":"2025-06-12T11:33:08.646Z","repository":{"id":57716237,"uuid":"43604611","full_name":"markzhai/init","owner":"markzhai","description":"Init helps app schedule complex task-group like initialization with type, priority and multi-process.","archived":false,"fork":false,"pushed_at":"2016-05-29T09:08:40.000Z","size":362,"stargazers_count":273,"open_issues_count":2,"forks_count":43,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-05-26T20:43:33.166Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://blog.zhaiyifan.cn/2015/10/04/init/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markzhai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-03T15:58:06.000Z","updated_at":"2025-02-06T01:13:13.000Z","dependencies_parsed_at":"2022-08-25T11:01:28.148Z","dependency_job_id":null,"html_url":"https://github.com/markzhai/init","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/markzhai/init","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markzhai%2Finit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markzhai%2Finit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markzhai%2Finit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markzhai%2Finit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markzhai","download_url":"https://codeload.github.com/markzhai/init/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markzhai%2Finit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259455748,"owners_count":22860426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T12:17:36.988Z","updated_at":"2025-06-12T11:33:08.607Z","avatar_url":"https://github.com/markzhai.png","language":"Java","funding_links":[],"categories":["并发编程"],"sub_categories":["Spring Cloud框架"],"readme":"# Init [![Maven Central](https://maven-badges.herokuapp.com/maven-central/cn.zhaiyifan/init/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/cn.zhaiyifan/init)\nInit helps app schedule complex task-group like initialization with type, priority and multi-process (you know that every process will run application's onCreate), thus improves efficiency.\n\nIt is originally designed for application initialization, but not confined to that, and can be applied to any complex task-group(like initialization procedure).\n\nThe library does not depend on any third-party library, it depends on Android in the case of Context and Log, and mostly depends on Java concurrent.\n\nIt's named Init for the sake of its original inspiration.\n\nSee [Wiki](https://github.com/markzhai/init/wiki) for detailed usage.\n\n[For Chinese 中文戳这里](https://github.com/markzhai/init/blob/master/README_CN.md)\n\n# How\n\nThe task-group(like initialization procedure) can be abstracted to flow, wave and task.\n\n![flow](art/flow.png \"how it works\")\n\nFlow is a coarse-grained concept, normally we have only one flow, but under certain condition, we may have several flow like patch flow, fake UI flow(to make user feel faster), broadcast flow, etc.\n\nEach wave can be started only when all blocked task in last wave finished, and all tasks belongs tothe wave will started at the same time(if no delay set).\n\nAs for task, they can be divided into two types\n 1. Blocked task, blue tasks in the picture.\n 2. Asynchronous task, can be\n- completely asynchronous or across several waves like the green task.\n- asynchronous task chain, like the two red tasks.\n\n# Usage\n\n```gradle\ndependencies {\n    compile 'cn.zhaiyifan:init:1.0.1'\n}\n```\n\n```java\npublic class DemoApplication extends Application {\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        // The library needs application context to get process information.\n        Init.init(this);\n        // Init.init(this, logProxy) enables custom log component\n        \n        Task task1 = new Task(\"task1\") {\n\n            @Override\n            protected void start() {\n                doSomeThing();\n            }\n\n            // when runs on process which makes the method return true\n            @Override\n            public boolean runOnProcess(String processName) {\n                return processName.equals(\"cn.zhaiyifan.demo\");\n            }\n        };\n        \n        // Create a task which is not blocked with 300 milliseconds delay.\n        Task task2 = new Task(\"task2\", false, 300) {\n\n            @Override\n            protected void start() {\n                doSomeThing();\n            }\n        };\n\n        // Create more tasks named task3, task4, task5, etc.\n        ...\n\n        // This is like the two red tasks in the flow picture, task5 depends on task4.\n        task5.setParentTask(task4);\n\n        Flow flow = new Flow(\"flow\");\n        // Add task1 and task2 to wave1\n        flow.addTask(1, task1)\n                .addTask(1, task2)\n                // Add task3 and task4 to wave2\n                .addTask(2, task3)\n                .addTask(2, task4)\n                // Add task5 and task4 to wave3, task5 can be started only after task4 finished\n                .addTask(3, task5);\n\n        Init.start(flow);\n    }\n```\n\nLet's have a look at log, we can see that the initialization which may take up to 2700ms only run 1307ms now.\n```log\n10-04 18:53:54.789 646-666/cn.zhaiyifan.init I/Task: task2 runs 500\n10-04 18:53:55.289 646-665/cn.zhaiyifan.init I/Task: task1 runs 1000\n10-04 18:53:55.591 646-741/cn.zhaiyifan.init I/Task: task3 runs 300\n10-04 18:53:55.592 646-646/cn.zhaiyifan.init I/Flow: flow runs 1307\n10-04 18:53:55.990 646-740/cn.zhaiyifan.init I/Task: task4 runs 700\n10-04 18:53:56.191 646-783/cn.zhaiyifan.init I/Task: task5 runs 200\n```\n\nSee demo project for more details.\n\nUseful api: \n```java\n// to set thread pool size\nInit.setThreadPoolSize(...)\n\n// cancel a started flow\nInit.cancel(...)\n\n// get flow status\nInit.getFlowStatus(...)\n\n// get specific task status\nflow.getTaskStatus(taskName)\n\n// set timeout, may not be useful for application init, but can be used for other init operation\nflow.setTimeout(5000)\n\netc.\n```\n\n# Why this\nImagine how we initialize a large application like Facebook, QQ, Wechat, etc, we will face sth like:\n\n```java\npublic class XXXApplication {\n\n    // for multi-dex apps\n    @Override\n    protected void attachBaseContext(Context base) {\n        // log init\n        ...\n        // eventbus init...\n        ...\n        // global variables init\n        ...\n        // process related\n        String processName = ...\n        boolean isMainProcess = ...\n        ProcessInit.attachBaseContext(this, processName, isMainProcess);\n    }\n\n    @Override\n    protected void onCreate() {\n        // process related\n        String processName = ...\n        boolean isMainProcess = ...\n\n        // CrashHandler, SafeMode, plugin, image manager, database, download, update, etc init\n\n        ProcessInit.onCreate(this, processName, isMainProcess);\n    }\n\n}\n\npublic class ProcessInit {\n    ...\n    public static void onCreate(Application application, boolean isMainProcess, String processName) {\n        if (isMainProcess) {\n\n        }\n    } else if (processName.contains(PUSH_PROCESS_SUFFIX)) {\n        ...\n    } else if (processName.contains(WEB_PROCESS_SUFFIX)) {\n        ...\n    } else if (processName.contains(MUSIC_PROCESS_SUFFIX)) {\n        ...\n    } else {\n        ...\n    }\n    ...\n}\n```\n\nYou see how complicated the initialization can be when the application grows, some operation should be after the other, and some can be done parallel, and some... Then we need to change the implementation of every init, to make some asynchronous, which makes code dirty and hard to understand.\n\nHow to make it simpler? I came up with this library.\n\n# Roadmap\n- 1.0 *October - A workable solution to principles mentioned above* DONE\n- 1.1 **In this year - Support more complex init flow** WIP\n- 2.0 Ability to reverse initialization code using this library to flow picture.\n\n# Contribute\nContribution is welcomed, you can create an issue or directly make a pull request.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkzhai%2Finit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkzhai%2Finit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkzhai%2Finit/lists"}