Android 车载性能优化-内存泄漏

内存监测工具

Android Studio 自带工具 Profiler

排查泄露的出处主要有两处:

  • CoroutineScope(Dispatchers.Main) 协程未释放
  • 匿名内部类对外部类有强引用

协程未释放

kotlin 复制代码
// CoroutineScope 未在 destroy 方法中 cancel
fun recycleViewScrollZoo() {
    LogUtils.i(TAG, "recycleViewScrollZoo")
    CoroutineScope(Dispatchers.Main).launch{
        FlowBus.events.collect{ event ->
            when(event){
                is EventWidget -> {
                    LogUtils.i(TAG, "recycleViewScrollZoo event.widgetName = : ${event.widgetName}")
                    scrollByWidgetName(event.widgetName)
                }
            }
        }
    }
}

造成内存泄漏的情况

选择一个类,可以查看具体的泄漏对象

解决方案

找到泄漏对象,在 destroy 方法中 cancel 任务

匿名内部类

kotlin 复制代码
private val mainHandler = Handler(Looper.getMainLooper())

// 匿名内部类
private val launcherStyleObserver = object : ContentObserver(mainHandler) {

    override fun onChange(selfChange: Boolean, uri: Uri?) {
        super.onChange(selfChange, uri)
        if (uri != null && uri.toString() == Settings.Global.getUriFor(KEY_LAUNCHER_STYLE)
                .toString()
        ) {
            startHomeWhenInBackGround()
            updateLauncherStyle()
        }
    }
}

匿名内部类持有外部类的引用,修改代码如下:

kotlin 复制代码
private val launcherStyleObserver = LauncherStyleObserver(mainHandler, this)
// 使用静态内部类和弱引用:将匿名内部类改为静态内部类,并使用弱引用持有外部类的引用
private class LauncherStyleObserver(handler: Handler, activity: MainActivity) : ContentObserver(handler) {

    // 弱引用
    private val activityReference = WeakReference(activity)
    override fun onChange(selfChange: Boolean, uri: Uri?) {
        super.onChange(selfChange, uri)
        val activity = activityReference.get()
        if (uri != null && uri.toString() == Settings.Global.getUriFor(KEY_LAUNCHER_STYLE)
                .toString()
        ) {
            activity?.startHomeWhenInBackGround()
            activity?.updateLauncherStyle()
        }
    }
}

解决方案:使用静态内部类和弱引用,将匿名内部类改为静态内部类,并使用弱引用持有外部类的引用

相关推荐
工程师老罗3 小时前
我用AI学Android Jetpack Compose之理解声明式UI
android·ui·android jetpack
锋风Fengfeng4 小时前
安卓Activity执行finish后onNewIntent也执行了
android
tmacfrank4 小时前
Jetpack Compose 学习笔记(四)—— CompositionLocal 与主题
android·kotlin·android jetpack
且随疾风前行.5 小时前
重学 Android 自定义 View 系列(十):带指针的渐变环形进度条
android
网安墨雨6 小时前
[网络安全]DVWA之File Upload—AntSword(蚁剑)攻击姿势及解题详析合集
android·安全·web安全
Clockwiseee6 小时前
文件上传题目练习
android·服务器·安全·网络安全
_明川7 小时前
Android 性能优化:内存优化(实践篇)
android·性能优化
Railshiqian8 小时前
ubuntu常用快捷键和变量记录
android·ubuntu
等一场春雨9 小时前
window11 wsl mysql8 错误分析:1698 - Access denied for user ‘root‘@‘kong.mshome.net‘
android·kong
lichong9519 小时前
【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100)
android·flutter·api·postman·smartapi·postapi·foxapi