🔥The Android Startup library provides a straightforward, performant way to initialize components at the application startup. Both library developers and app developers can use Android Startup to streamline startup sequences and explicitly set the order of initialization.

Overview

English|中文

android-startup

Author Platform API Language Release Code Size License

The android-startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use android-startup to streamline startup sequences and explicitly set the order of initialization.

At the same time, the android-startup support async await and sync await. And topological ordering is used to ensure the initialization order of dependent components.

Here is a piece of with Google App Startup feature comparison table.

indicator App Startup Android Startup
Manually Config
Automatic Config
Support Dependencies
Handle Circle
Thread Of Control
Async Await
Callback Dependencies
Manual Notify
Topology Optimization
Time Cost Statistics
Thread Priority
Multiple Processes

Open source is not easy, I hope friends shake hands, a star in the upper right corner, thank you 🙏

Related Articles

Why I abandoned the Jetpack App Startup?

Android Startup Analysis

Setup

Add the following dependency to your build.gradle file:

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.github.idisfkj:android-startup:1.0.7'
}

Versions update information: Release

Quick Usage

There are tow ways of using android-startup in your project,need to be initialized before using android-startup.

Define Initialize components

You define each component initializer by creating a class that implements the AndroidStartup abstract. This abstract implements the Startup interface. And this abstract defines four important methods:

  • The callCreateOnMainThread(): Booleanmethod,which control the create()method is in the main thread calls.Othrewise in the other thread.

  • The waitOnMainThread(): Booleanmethod,which control the current component should call waiting in the main thread.If returns true, will block the main thread.

  • The create(): T?method,which contains all of the necessary operations to initialize the component and returns an instance of T

  • The dependencies(): List >>? method,which returns a list of the other Startup<*> objects that the initializer depends on.

For example, Define a SampleFirstStartup class that implements AndroidStartup :

class SampleFirstStartup : AndroidStartup
   
    () {

    override fun callCreateOnMainThread(): Boolean = true

    override fun waitOnMainThread(): Boolean = false

    override fun create(context: Context): String? {
        // todo something
        return this.javaClass.simpleName
    }

    override fun dependencies(): List
    
     
      >>? {
        return null
    }

}

     
    
   

The dependencies() method returns an null list because SampleFirstStartup does not depend on any other libraries.

Suppose that your app also depends on a library called SampleSecondStartup, which in turn depends on SampleFirstStartup. This dependency means that you need to make sure that Android Startup initializes SampleFirstStartup first.

class SampleSecondStartup : AndroidStartup
   
    () {

    override fun callCreateOnMainThread(): Boolean = false

    override fun waitOnMainThread(): Boolean = true

    override fun create(context: Context): Boolean {
        // Simulation execution time.
        Thread.sleep(5000)
        return true
    }

    override fun dependencies(): List
    
     
      >>? {
        return listOf(SampleFirstStartup::class.java)
    }

}

     
    
   

Because you include SampleFirstStartup in the dependencies() method, Android Startup initializes SampleFirstStartup before SampleSecondStartup.

For example, you also define a SampleThirdStartup and a SampleFourthStartup

Automatic initialization in manifest

The first one is automatic initializes startup in manifest.

Android Startup includes a special content provider called StartupProvider that it uses to discover and call your component startup. In order for it to automatically identify, need in StartupProvider defined in the label.The name as defined by the component class, value values corresponding to the android.startup.

">

   

    
    


   

You don't need to add a entry for SampleFirstStartup, SampleSecondStartup and SampleThirdStartup, because them are a dependency of SampleFourthStartup. This means that if SampleFourthStartup is discoverable, then are also.

Manually initialization in application

The second one is manually initializes startup in application.

Consider again the example,to make sure Android Startup can initializes,you can use StartupManager.Builder() directly in order to manually initialize components.

For example, the following code calls StartupManager.Builder() and manually initializes them:

class SampleApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        StartupManager.Builder()
            .addStartup(SampleFirstStartup())
            .addStartup(SampleSecondStartup())
            .addStartup(SampleThirdStartup())
            .addStartup(SampleFourthStartup())
            .build(this)
            .start()
            .await()
    }
}

You can check out the sample app for more code information.

Run the example code, the console will produce the log as follows:

  1. After the initialization sequence sorting optimization
*****/com.rousetime.sample D/StartupTrack: TopologySort result:
    |================================================================
    |         order          |    [1]
    |----------------------------------------------------------------
    |        Startup         |    SampleFirstStartup
    |----------------------------------------------------------------
    |   Dependencies size    |    0
    |----------------------------------------------------------------
    | callCreateOnMainThread |    true
    |----------------------------------------------------------------
    |    waitOnMainThread    |    false
    |================================================================
    |         order          |    [2]
    |----------------------------------------------------------------
    |        Startup         |    SampleSecondStartup
    |----------------------------------------------------------------
    |   Dependencies size    |    1
    |----------------------------------------------------------------
    | callCreateOnMainThread |    false
    |----------------------------------------------------------------
    |    waitOnMainThread    |    true
    |================================================================
    |         order          |    [3]
    |----------------------------------------------------------------
    |        Startup         |    SampleThirdStartup
    |----------------------------------------------------------------
    |   Dependencies size    |    2
    |----------------------------------------------------------------
    | callCreateOnMainThread |    false
    |----------------------------------------------------------------
    |    waitOnMainThread    |    false
    |================================================================
    |         order          |    [4]
    |----------------------------------------------------------------
    |        Startup         |    SampleFourthStartup
    |----------------------------------------------------------------
    |   Dependencies size    |    3
    |----------------------------------------------------------------
    | callCreateOnMainThread |    false
    |----------------------------------------------------------------
    |    waitOnMainThread    |    false
    |================================================================
  1. Consumed components initialization times
*****/com.rousetime.sample D/StartupTrack: startup cost times detail:
    |=================================================================
    |      Startup Name       |   SampleFirstStartup
    | ----------------------- | --------------------------------------
    |   Call On Main Thread   |   true
    | ----------------------- | --------------------------------------
    |   Wait On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |       Cost Times        |   0 ms
    |=================================================================
    |      Startup Name       |   SampleSecondStartup
    | ----------------------- | --------------------------------------
    |   Call On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |   Wait On Main Thread   |   true
    | ----------------------- | --------------------------------------
    |       Cost Times        |   5001 ms
    |=================================================================
    |      Startup Name       |   SampleThirdStartup
    | ----------------------- | --------------------------------------
    |   Call On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |   Wait On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |       Cost Times        |   3007 ms
    |=================================================================
    |      Startup Name       |   SampleFourthStartup
    | ----------------------- | --------------------------------------
    |   Call On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |   Wait On Main Thread   |   false
    | ----------------------- | --------------------------------------
    |       Cost Times        |   102 ms
    |=================================================================
    | Total Main Thread Times |   5008 ms
    |=================================================================

More

Optional Config

  • LoggerLevel: Control Android Startup log level, include LoggerLevel.NONE, LoggerLevel.ERROR and LoggerLevel.DEBUG.

  • AwaitTimeout: Control Android Startup timeout of await on main thread.

  • StartupListener: Android Startup listener, all the component initialization completes the listener will be called.

  • OpenStatistic: Control the elapsed time statistics for each Android Startup task.

config in manifest

To use these config, you must define a class than implements the StartupProviderConfig interface:

class SampleStartupProviderConfig : StartupProviderConfig {

    override fun getConfig(): StartupConfig =
        StartupConfig.Builder()
            .setLoggerLevel(LoggerLevel.DEBUG) // default LoggerLevel.NONE
            .setAwaitTimeout(12000L) // default 10000L
            .setOpenStatistics(true) // default true
            .setListener(object : StartupListener {
                override fun onCompleted(totalMainThreadCostTime: Long, costTimesModels: List
   
    ) {
                    // can to do cost time statistics.
                }
            })
            .build()
}

   

At the same time, you need add StartupProviderConfig to manifest file:

">

   

    
    


   

StartupProvider that it uses to discover and call SampleStartupProviderConfig.

config in application

To use these config,you need use StartupManager.Builder() in application.

override fun onCreate() {
    super.onCreate()

    val config = StartupConfig.Builder()
        .setLoggerLevel(LoggerLevel.DEBUG)
        .setAwaitTimeout(12000L)
        .setListener(object : StartupListener {
            override fun onCompleted(totalMainThreadCostTime: Long, costTimesModels: List
   
    ) {
                // can to do cost time statistics.
            }
        })
        .build()

    StartupManager.Builder()
        .setConfig(config)
        ...
        .build(this)
        .start()
        .await()
}

   

AndroidStartup

  • createExecutor(): Executor: If the startup not create on main thread, them the startup will run in the executor.

  • onDependenciesCompleted(startup: Startup<*>, result: Any?): This method is called whenever there is a dependency completion.

  • manualDispatch(): Boolean: Returns true that manual to dispatch. but must be call onDispatch(), in order to notify children that dependencies startup completed.

  • onDispatch(): Start to dispatch when manualDispatch() return true.

StartupCacheManager

  • hadInitialized(zClass: Class >) : Check whether the corresponding component initialization has been completed.

  • obtainInitializedResult(zClass: Class >): T? : Obtain corresponding components of has been initialized the returned results.

  • remove(zClass: Class >) : To get rid of the corresponding component initialization cache the results.

  • clear(): Remove all the component initialization cache the results.

Annotation

  • ThreadPriority: Set Startup to initialize thread priority.

  • MultipleProcess: The process on which Startup is initialized.

Sample

License

Please see LICENSE

Comments
  • manualDispatch的问题

    manualDispatch的问题

    大佬,我运行了demo中的SampleManualDispatchStartup代码。发现SampleAsyncSevenStartup的onDependenciesCompleted在SampleManualDispatchStartup的onDispatch()方法前就已经获取到了。。这个逻辑感觉很奇怪啊,被依赖的组件还没有手动调用onDispatch,其他组件就已经获取到result了,这个result没啥用。我现在使用场景就是“请求权限的组件”被“初始化统计库的组件”依赖,“请求权限的组件”会通过回调的方式把结果赋值给result,发现“初始化统计库的组件”的onDependenciesCompleted方法在“请求权限的组件”的回调之前就已经运行了。

    opened by android-1995 6
  • 多进程task,为什么要直接在AndroidStartup中指定?

    多进程task,为什么要直接在AndroidStartup中指定?

    多进程都需要启动的task要怎么处理

    if ((TextUtils.isEmpty(process) && ProcessUtils.isMainProcess(context)) || ProcessUtils.isMultipleProcess(context, process)) { realStartupList.add(it) if (it.waitOnMainThread() && !it.callCreateOnMainThread()) { mNeedAwaitCount.incrementAndGet() } }

    opened by YangCheung 6
  • LeakCanary报的内存泄露

    LeakCanary报的内存泄露

    LeakCanary报告

    2021-10-10 09:47:06.510 6343-6343/com.aiwu.myapplication D/LeakCanary: ​
        ┬───
        │ GC Root: Local variable in native code
        │
        ├─ android.os.HandlerThread instance
        │    Leaking: NO (PathClassLoader↓ is not leaking)
        │    Thread name: 'LeakCanary-Heap-Dump'
        │    ↓ Thread.contextClassLoader
        ├─ dalvik.system.PathClassLoader instance
        │    Leaking: NO (StartupCacheManager↓ is not leaking and A ClassLoader is never leaking)
        │    ↓ ClassLoader.runtimeInternalObjects
        ├─ java.lang.Object[] array
        │    Leaking: NO (StartupCacheManager↓ is not leaking)
        │    ↓ Object[].[1131]
        ├─ com.rousetime.android_startup.manager.StartupCacheManager class
        │    Leaking: NO (a class is never leaking)
        │    ↓ static StartupCacheManager.instance$delegate
        │                                 ~~~~~~~~~~~~~~~~~
        ├─ kotlin.SynchronizedLazyImpl instance
        │    Leaking: UNKNOWN
        │    Retaining 78.3 kB in 1199 objects
        │    ↓ SynchronizedLazyImpl._value
        │                           ~~~~~~
        ├─ com.rousetime.android_startup.manager.StartupCacheManager instance
        │    Leaking: UNKNOWN
        │    Retaining 78.3 kB in 1198 objects
        │    ↓ StartupCacheManager.initializedConfig
        │                          ~~~~~~~~~~~~~~~~~
        ├─ com.rousetime.android_startup.model.StartupConfig instance
        │    Leaking: UNKNOWN
        │    Retaining 78.1 kB in 1193 objects
        │    ↓ StartupConfig.listener
        │                    ~~~~~~~~
        ├─ com.aiwu.myapplication.SplashActivity$task$1 instance
        │    Leaking: UNKNOWN
        │    Retaining 78.1 kB in 1192 objects
        │    Anonymous class implementing com.rousetime.android_startup.StartupListener
        │    this$0 instance of com.aiwu.myapplication.SplashActivity with mDestroyed = true
        │    ↓ SplashActivity$task$1.this$0
        │                            ~~~~~~
        ╰→ com.aiwu.myapplication.SplashActivity instance
        ​     Leaking: YES (ObjectWatcher was watching this because com.aiwu.myapplication.SplashActivity received
        ​     Activity#onDestroy() callback and Activity#mDestroyed is true)
        ​     Retaining 78.0 kB in 1191 objects
        ​     key = 2490bb45-30d7-4fcc-a5b8-0c6c25215341
        ​     watchDurationMillis = 11702
        ​     retainedDurationMillis = 6700
        ​     mApplication instance of android.app.Application
        ​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
        
        METADATA
        
        Build.VERSION.SDK_INT: 30
        Build.MANUFACTURER: Google
        LeakCanary version: 2.7
        App process name: com.aiwu.myapplication
        Stats: LruCache[maxSize=3000,hits=2278,misses=59102,hitRate=3%]
        RandomAccess[bytes=2891587,reads=59102,travel=23161836688,range=17719770,size=23455318]
        Heap dump reason: user request
        Analysis duration: 9374 ms
    

    测试代码

    class SplashActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            task()
        }
    
        private fun task() {
            StartupManager.Builder()
                .addStartup(TestStartup())
                .setConfig(
                    StartupConfig.Builder()
                        .setLoggerLevel(LoggerLevel.DEBUG)
                        .setListener(object : StartupListener {
                            override fun onCompleted(
                                totalMainThreadCostTime: Long,
                                costTimesModels: List<CostTimesModel>
                            ) {
                                goMainAct()
                            }
                        })
                        .build()
                )
                .build(this)
                .start()
                .await()
        }
    
        private fun goMainAct() {
            startActivity(Intent(this, MainActivity::class.java))
            finish()
        }
    
        class TestStartup : AndroidStartup<Boolean>() {
            override fun callCreateOnMainThread() = false
    
            override fun waitOnMainThread() = false
    
            override fun create(context: Context): Boolean {
                Thread.sleep(1000)
                return true
            }
        }
    }
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
    
    opened by android-1995 3
  • 在自己的组件化项目试用了下

    在自己的组件化项目试用了下

    app module依赖了module1、module2 1、app module中写了AppStartUp,通过app module的manifest配置了provider和AppStartup 2、module1和module2分别有自己的module1StartUp和module2StartUp,并且都在在各自的Manifest中声明了 3、运行app,manifest的meta-data会合并,但是startup的执行顺序并不是合并后的那个顺序

    所以manifest中声明多个StartUp的时候,这几个StartUp是不会按照声明顺序执行的吧?

    opened by caihuanjian 3
  • Remove Logging from library

    Remove Logging from library

    Hi, for better performance of your library will be better to delete all of logging code, because it spends time and allocates a lot of objects, and also it uses reflection api for getting class name and etc, usually this does lazily putting arguments and formatted/concatenated on demand. LoggerLevel settings nohow to helps here, because message will creates even with LoggerLevel.NONE for example:

    StartupLogUtils.d("${startup::class.java.simpleName} being dispatching, onMainThread ${startup.callCreateOnMainThread()}.")
    

    and somewhere I saw buildString with huge tables)

    opened by kuFEAR 2
  • 初始化失败问题

    初始化失败问题

    您好,我在Android9.0的设备上使用startup遇到初始化失败的问题。后来换用您的这个库,依然有相似的问题:

    Android10和Android11是ok的

    代码如下:

            <provider
                android:name="com.rousetime.android_startup.provider.StartupProvider"
                android:authorities="${applicationId}.android_startup"
                android:exported="false">
    
                <meta-data
                    android:name="com.example.xlulibrary.ToastLifecycle"
                    android:value="android.startup" />
    
            </provider>
    
    
    internal object ToastLifecycle : AndroidStartup<Unit>() {
    
        lateinit var application: Application
    
        override fun callCreateOnMainThread(): Boolean = false
    
        override fun create(context: Context) {
            application = context as Application
        }
    
        override fun dependencies(): List<Class<out Startup<*>>>? = null
    
        override fun waitOnMainThread(): Boolean = false
    }
    

    log如下:

    2021-12-03 17:30:32.927 9659-9659/com.example.toastbox E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.toastbox, PID: 9659
        java.lang.RuntimeException: Unable to get provider com.rousetime.android_startup.provider.StartupProvider: com.rousetime.android_startup.execption.StartupException: java.lang.IllegalAccessException: Class java.lang.Class<com.rousetime.android_startup.StartupInitializer> cannot access private  method void com.example.xlulibrary.ToastLifecycle.<init>() of class java.lang.Class<com.example.xlulibrary.ToastLifecycle>
            at android.app.ActivityThread.installProvider(ActivityThread.java:6396)
            at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853)
            at android.app.ActivityThread.access$1100(ActivityThread.java:199)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:6669)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
         Caused by: com.rousetime.android_startup.execption.StartupException: java.lang.IllegalAccessException: Class java.lang.Class<com.rousetime.android_startup.StartupInitializer> cannot access private  method void com.example.xlulibrary.ToastLifecycle.<init>() of class java.lang.Class<com.example.xlulibrary.ToastLifecycle>
            at com.rousetime.android_startup.StartupInitializer.discoverAndInitialize$android_startup_release(StartupInitializer.kt:55)
            at com.rousetime.android_startup.provider.StartupProvider.onCreate(StartupProvider.kt:19)
            at android.content.ContentProvider.attachInfo(ContentProvider.java:1919)
            at android.content.ContentProvider.attachInfo(ContentProvider.java:1894)
            at android.app.ActivityThread.installProvider(ActivityThread.java:6391)
            at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938) 
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853) 
            at android.app.ActivityThread.access$1100(ActivityThread.java:199) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650) 
            at android.os.Handler.dispatchMessage(Handler.java:106) 
            at android.os.Looper.loop(Looper.java:193) 
            at android.app.ActivityThread.main(ActivityThread.java:6669) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
         Caused by: java.lang.IllegalAccessException: Class java.lang.Class<com.rousetime.android_startup.StartupInitializer> cannot access private  method void com.example.xlulibrary.ToastLifecycle.<init>() of class java.lang.Class<com.example.xlulibrary.ToastLifecycle>
            at java.lang.reflect.Constructor.newInstance0(Native Method)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
            at com.rousetime.android_startup.StartupInitializer.discoverAndInitialize$android_startup_release(StartupInitializer.kt:43)
            at com.rousetime.android_startup.provider.StartupProvider.onCreate(StartupProvider.kt:19) 
            at android.content.ContentProvider.attachInfo(ContentProvider.java:1919) 
            at android.content.ContentProvider.attachInfo(ContentProvider.java:1894) 
            at android.app.ActivityThread.installProvider(ActivityThread.java:6391) 
            at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938) 
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853) 
            at android.app.ActivityThread.access$1100(ActivityThread.java:199) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650) 
            at android.os.Handler.dispatchMessage(Handler.java:106) 
            at android.os.Looper.loop(Looper.java:193) 
            at android.app.ActivityThread.main(ActivityThread.java:6669) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
    2021-12-03 17:30:32.934 9659-9659/com.example.toastbox I/Process: Sending signal. PID: 9659 SIG: 9
    
    

    希望大佬能看下😄

    opened by xluu233 2
  • 在AndroidManifest中配置的StartupProviderConfig一定会被打进主dex包吗?

    在AndroidManifest中配置的StartupProviderConfig一定会被打进主dex包吗?

    大佬好,我有一个疑问,就是项目比较庞大的时候,分成了很多个模块,每个模块里面都会有如下的配置:

    <provider
        android:name="com.rousetime.android_startup.provider.StartupProvider"
        android:authorities="${applicationId}.android_startup"
        android:exported="false">
        <meta-data
            android:name="com.rousetime.sample.startup.SampleStartupProviderConfigX"
            android:value="android.startup.provider.config" />
    </provider>
    

    因为65535的问题,class文件会被分到多个dex包,那我打包的时候,meta-data里配置的类会不会不在主dex包内? 如果出现这种情况,app还能正常启动吗?

    opened by wangkunhui 2
  • StartupCostTimesUtils LinkedHashMap crashes

    StartupCostTimesUtils LinkedHashMap crashes

    Hi, StartupCostTimesUtils uses LinkedHashMap for storing CostTimesModel, but StartupCostTimesUtils#recordStart is called from different threads. In some cases there were crashes.

    Can you please add the ability to disable statistics for release builds?

    Thanks!

    Crashes:

    Fatal Exception: java.lang.ArrayIndexOutOfBoundsException: length=16; index=28
           at java.util.LinkedHashMap.addNewEntry(LinkedHashMap.java:197)
           at java.util.HashMap.put(HashMap.java:403)
           at com.rousetime.android_startup.utils.StartupCostTimesUtils.recordStart(StartupCostTimesUtils.java:24)
           at com.rousetime.android_startup.run.StartupRunnable.run(StartupRunnable.java:31)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
           at java.lang.Thread.run(Thread.java:818)
    

    For Android 7 (maybe a bug in android implementation of LinkedHashMap):

    Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'int java.util.HashMap$HashMapEntry.hash' on a null object reference
           at java.util.LinkedHashMap.transfer(LinkedHashMap.java:273)
           at java.util.HashMap.resize(HashMap.java:512)
           at java.util.HashMap.addEntry(HashMap.java:808)
           at java.util.LinkedHashMap.addEntry(LinkedHashMap.java:464)
           at java.util.HashMap.put(HashMap.java:436)
           at com.rousetime.android_startup.utils.StartupCostTimesUtils.recordStart(StartupCostTimesUtils.java:24)
           at com.rousetime.android_startup.run.StartupRunnable.run(StartupRunnable.java:31)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
           at java.lang.Thread.run(Thread.java:762)
    
    bug 
    opened by dmitriyTarasov 2
  • 异常问题

    异常问题

    使用了这个库之后, bugly收到了很多异常信息.. #56515 SIGABRT #86512 SIGABRT 很多类似的问题

    #00 pc 0001afb8 /system/lib/libc.so (abort+100) [armeabi-v8] 2 #01 pc 0035b311 /system/lib/libart.so (art::Runtime::Abort(char const*)+392) [armeabi-v8] ..... com.xxxx.constants.InitTool.initPush(InitTool.java:69) com.xxxx..common.startup.InitPushStartup.create(InitPushStartup.java:28) com.xxxx..common.startup.InitPushStartup.create(InitPushStartup.java:17)

    代码: public Boolean create(@NotNull Context context) { InitTool.initPush(applictaion); ---->> Line 28 return null; }

    opened by dongliwu520 2
  • 想问下大家这个库有用在大日活的生产环境吗?

    想问下大家这个库有用在大日活的生产环境吗?

    我们的启动任务比较复杂,await函数爆出大量的anr问题,大家有遇到过这种情况吗?

    sun.misc.Unsafe.park(Unsafe.java) java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230) java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1063) java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1358) java.util.concurrent.CountDownLatch.await(CountDownLatch.java:278)

    opened by ld2006203 1
  • Benefit of Topological Sort in Async Initialization

    Benefit of Topological Sort in Async Initialization

    Itssssss Rousetime!

    Thanks for the great library! It's exactly what I'm looking for to perform multithreaded, eager initialization of app startup.

    What is the benefit to the topological sort for a series of async dependencies? Assuming we have a set of N-number Android Startups, none of which require main thread, we'd end up with N latched Runnables. It seems it'd just be first-to-finish as each Runnable is unlatched and completed, and the order these Runnables are dispatched to an executor won't matter, assuming we have N-number threads available. I suppose if the underlying thread pool is limited to X-number threads, then the sort guarantees the order of Runnables getting access to the pool.

    Any other insight here?

    Thanks!

    opened by kbabcockuf 1
  • 一点建议,希望能结合provider初始化的优点

    一点建议,希望能结合provider初始化的优点

    显示的初始化,不利于组件解耦和组件单独运行,所以希望能结合provider初始化的优点 1组件的初始化依然继承AndroidStartup,但是把声明信息放到组件自己的AndroidManifest.xml的下的<meta-data里 2android-startup库使用provider初始化自身,然后读取<meta-data的配置初始化各个AndroidStartup 3 dependencies方法返回值使用String,使用绝对地址"com.xxx.xxx.xxStartup" 4或者可以选择使用注解来声明初始化信息,注解处理器在编译时处理,生成相应初始化代码

    opened by edwardZj 1
Releases(1.1.0)
  • 1.1.0(Dec 29, 2021)

    New Feature And Optimizes

    • Feat: Support dependency using class names.
    • Optimize: Optimize log system and time statistics system.

    Full Changelog: https://github.com/idisfkj/android-startup/compare/1.0.7...1.1.0

    Source code(tar.gz)
    Source code(zip)
  • 1.0.7(Jul 19, 2021)

    New Feature And Fix Bug

    • Feat: Provide the openStatistic parameter in StartupConfig to set the statistics switch.
    • Fix: Use ConcurrentHashMap to replace LinkedHashMap to solve the problem of multithreading concurrency.
    • Fix: Resolve log length being intercepted.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.6(Nov 24, 2020)

  • 1.0.5(Sep 20, 2020)

  • 1.0.4(Sep 16, 2020)

    New Feature

    • Feat: Add the annotation MultipleProcess to support components of multi-process initialization.
    • Feat: Add the annotation ThreadPriority to support set component initialization thread priority.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Aug 18, 2020)

    New Feature And Fix Bug

    • Feat: Add startup trace.
    • Feat: Add manual dispatch to notify children that dependencies completed.
    • Feat: Add proguard files.
    • Fix: Adjust main thread cost time statistics.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Aug 11, 2020)

    New Feature And Optimizes

    • Optimize: Extract discover and Initialize logic from StartupProvider into StartupInitializer.
    • Feat: Add support cache to the initialized component.
    • Feat: Add support cost times statistics and listener.
    • Optimize: Change the type of Class to String in sort and initialize.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Jul 31, 2020)

    New Feature And Fix Bug

    • Feat: Add StartupConfig to initialize android startup config.
    • Fix: Remove useless startup.toNotify() call.
    • Fix: Adjust notifyChildren() method.
    • Feat: Optimize log output.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Jul 29, 2020)

Owner
Rouse
Android & small program & front end engineer, dedicated to big front end, lifelong learner.
Rouse
Service exposes sensitive administration APIs to initialize and set lower level of Slurpanize infrastructure

slurpanize-baker Project This project uses Quarkus, the Supersonic Subatomic Java Framework. If you want to learn more about Quarkus, please visit its

Slurpanize by Tetracube RED 0 Nov 25, 2021
Demo Spting REST Service on Kotlin. Works with PostgreSQL via Spring Data. Data initialization provided by liquibase

Spring Boot REST API with Kotlin Spring Boot REST API service. Spring Data with PostgreSQL. Data initialization with Liquibase. Swagger UI Reference D

null 0 Jun 10, 2022
Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

JetBrains 10k Jan 7, 2023
Shreyas Patil 2.2k Jan 4, 2023
This prototype app provides a list of events to be held under an organization (school, college, club, etc.) and the users can manually set event reminders at their scheduled time so that they do not miss an event.

E-CELL NITS Sample App This prototype app provides a list of events to be held under E-Cell NIT Silchar (for example, Srijan 2.0) and the users can ma

Ritam Nath 1 Nov 7, 2021
Flexible switch is a responsive switch with some nice features which developers can use for making awesome switches on android platform.

flexible-switch It is a responsive switch in android, it can resize itself according to its size. It's recommended to use it with ConstraintLayout to

Coders Route 5 Dec 20, 2022
Set of extensions for Kotlin that provides Discrete math functionalities

DiscreteMathToolkit Set of extensions for Kotlin that provides Discrete Math functionalities as an Kotlin extension functions. To stay current with ne

Marcin Moskała 177 Dec 15, 2022
A counter down timer for android which supports both dark and light mode and Persian text and digit.

FlipTimerView A counter down timer for android which supports both dark and light mode and Persian text and digit. English Perisan Getting started Ste

Arezoo Nazer 7 Jul 17, 2022
Training a dense neural network using both KotlinDL and Python3 on the mnist dataset.

KotlinDL-mnist KotlinDL: Deep Learning Framework written in Kotlin This project trains a dense neural network using both KotlinDL and Python3 on the m

Wu Han 2 Apr 7, 2022
The app contains an order flow for cupcakes with options for quantity, flavor, and pickup date

Cupcake app This app contains an order flow for cupcakes with options for quantity, flavor, and pickup date. The order details get displayed on an ord

null 0 Nov 13, 2021
An e-commerce app which provide a new platform to order food items from various restaurants

Food_App_Internshala An e-commerce app which provide a new platform to order food items from various restaurants. Splash and Login Page Opening of the

Partha Sarathi Sahu 0 Apr 26, 2022
A library that extends the existing JDBC API so that data objects can be used as input (to set parameters) and output (from ResultSet's rows).

SqlObjectMapper This is a library that extends the existing JDBC API so that data objects can be used as input (to set parameters) and output (from Re

Qualified Cactus 2 Nov 7, 2022
Data structures in kotlin that maintain order

Ordered Data Structures I came from C++ and fell in love with kotlin. I used the C++ stdlib a lot. I have really been wanted to reach for map and unor

Kyle McBurnett 0 Nov 1, 2021
Project created in order to handle account management

Account Service App Aplicação responsável em receber dados de uma conta, validá-los e retornar mensagem de sucesso ou erro. Tecnologias utilizadas - L

Rafael Alberto 0 Dec 14, 2021
Cago provides you way to do complex calculations on your device.

Cago Do your calculations easier. Cago provides you way to do complex calculations on your device. You can build functions that fit your goals by your

null 0 Feb 13, 2022
Use Android Jetpack libraries, Android Architecture Components, ViewModel and LiveData to build this app.

Unscramble App Starter code for Android Basics codelab - Store the data in a ViewModel Unscramble is a single player game app that displays scrambled

Shaima Alghamdi 2 Aug 18, 2022
A learning project which focuses on designing an OTP flow and use of various components of Android efficiently

Otp Demo A learning project which focuses on designing an OTP flow using Firebase. Article: https://saurabhpant.medium.com/otp-login-using-firebase-hi

Saurabh Pant 27 Dec 22, 2022
An application with the use of Kotlin can change the color of the text, and the background with the press of a button and switch.

An application with the use of Kotlin can change the color of the text, and the background with the press of a button and switch.

Robert Velasquez 2 Jul 20, 2022
An Android app that scans images or human faces in real time and detects whether the mask is worn or not, with the ability to set an audible alert

Swift Mask Real time face mask detection Brief overview Swift Mask scans images or human faces in real time and detects whether the mask is worn or no

Giorgio Cantoni 4 Sep 22, 2022