idisfkj / android-startup

🔥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.
https://rousetime.com
Apache License 2.0
1.6k stars 158 forks source link

LeakCanary报的内存泄露 #20

Closed android-1995 closed 3 years ago

android-1995 commented 3 years ago

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)
    }
}
android-1995 commented 3 years ago

依赖

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
    implementation 'io.github.idisfkj:android-startup:1.0.7'
idisfkj commented 3 years ago

AndroidStartup手动初始化原则上规定是在Application中进行初始化。

建议再去看下README。

android-1995 commented 3 years ago

好吧,我当成任务流程框架用了。谢谢