From 21d6c665f3982bb2d47103b7803bcce2032cdfa8 Mon Sep 17 00:00:00 2001 From: renwj Date: Fri, 3 Feb 2023 17:31:45 +0800 Subject: [PATCH] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0][leakfix]=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E7=94=B1=E4=BA=8E=E5=8C=BF=E5=90=8DRunnable=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=BC=95=E7=94=A8=E5=A4=96=E9=83=A8=E7=B1=BB=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E9=80=A0=E6=88=90=E7=9A=84=E5=86=85=E5=AD=98=E6=B3=84?= =?UTF-8?q?=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 + .../com/mogo/launcher/lancet/MemoryLeakFix.kt | 94 +++++++++++++++++++ build.gradle | 2 +- config.gradle | 2 +- 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/mogo/launcher/lancet/MemoryLeakFix.kt diff --git a/app/build.gradle b/app/build.gradle index 71abf1ea14..e70a3c65ef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,6 +61,9 @@ if (!isAndroidTestBuild()) { crash_fix { enable true } + memory_leak { + enable true + } } } } diff --git a/app/src/main/java/com/mogo/launcher/lancet/MemoryLeakFix.kt b/app/src/main/java/com/mogo/launcher/lancet/MemoryLeakFix.kt new file mode 100644 index 0000000000..4b9374ed5f --- /dev/null +++ b/app/src/main/java/com/mogo/launcher/lancet/MemoryLeakFix.kt @@ -0,0 +1,94 @@ +package com.mogo.launcher.lancet + +import android.app.Activity +import android.app.Dialog +import android.content.Context +import android.view.View +import androidx.annotation.* +import androidx.core.view.ViewCompat +import androidx.fragment.app.* +import com.knightboost.lancet.api.* +import com.knightboost.lancet.api.annotations.* +import com.knightboost.lancet.api.annotations.Weaver +import com.mogo.eagle.core.utilcode.kotlin.* +import java.lang.ref.* +import java.lang.reflect.Modifier +import java.util.concurrent.ConcurrentHashMap + +@Keep +@Weaver +@Group("memory_leak") +class MemoryLeakFix { + + @Insert + @ImplementedInterface("java.lang.Runnable") + @TargetMethod(methodName = "run") + fun runProxy() { + if (AccessSyntheticUtils.isTargetAlive(This.get())) { + Origin.callVoid() + } + } +} + +internal class AccessSyntheticUtils { + + companion object { + + private val fields = ConcurrentHashMap>() + + @JvmStatic + fun isTargetAlive(obj: Any): Boolean { + try { + val clazz = obj.javaClass + if (!clazz.isAnonymousClass) { + return true + } + val key = clazz.name + return (fields[key] ?: clazz.declaredFields.find { + it.isSynthetic && + ((it.modifiers and Modifier.STATIC) == 0) && + (View::class.java.isAssignableFrom(it.type) or + Context::class.java.isAssignableFrom(it.type) or + Fragment::class.java.isAssignableFrom(it.type) or + android.app.Fragment::class.java.isAssignableFrom(it.type) or + Dialog::class.java.isAssignableFrom(it.type) + ) + }?.let { + it.isAccessible = true + val wf = WeakReference(it.get(obj), ReferenceQueue()) + fields[key] = wf + wf + })?.also { + if (it.isEnqueued) { + //对像被垃圾回收了 + fields.remove(key) + } + }?.get()?.let { t -> + when(t) { + is View -> { + ViewCompat.isAttachedToWindow(t) + } + is Activity -> { + !t.isFinishing && !t.isDestroyed + } + is Fragment -> { + !t.isDetached + } + is android.app.Fragment -> { + !t.isDetached + } + is Dialog -> { + t.window?.decorView?.let { v -> ViewCompat.isAttachedToWindow(v) } ?: false + } + else -> { + true + } + } + } ?: true + } catch (t: Throwable) { + t.printStackTrace() + } + return true + } + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 66ec9a72f2..cbd64fba4f 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ buildscript { classpath 'com.mogo.cloud:systrace:1.0.1' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18' classpath 'com.mogo.sticky:service:1.0.8' - classpath 'io.github.knight-zxw:lancet-plugin:0.0.1' + classpath 'io.github.knight-zxw:lancet-plugin:0.0.4' // classpath ("com.tencent.matrix:matrix-gradle-plugin:0.6.6") { changing = true } } diff --git a/config.gradle b/config.gradle index 2ee5bb5335..d073b6b0a7 100644 --- a/config.gradle +++ b/config.gradle @@ -220,7 +220,7 @@ ext { //========================= LancetX =================== - lancetx_runtime : "io.github.knight-zxw:lancet-runtime:0.0.1", + lancetx_runtime : "io.github.knight-zxw:lancet-runtime:0.0.4", //========================= autosize ====================== androidautoSize : 'com.github.JessYanCoding:AndroidAutoSize:v1.2.1',