[2.15.0] 优化子线程切主线程操作

This commit is contained in:
renwj
2023-03-27 20:40:51 +08:00
parent e14bde9129
commit 0beb152ab0
5 changed files with 64 additions and 53 deletions

View File

@@ -1,10 +1,15 @@
package com.mogo.launcher.lancet
import android.app.Activity
import android.os.*
import android.view.View
import androidx.annotation.*
import com.knightboost.lancet.api.*
import com.knightboost.lancet.api.Scope.ALL
import com.knightboost.lancet.api.annotations.*
import com.knightboost.lancet.api.annotations.Weaver
import com.mogo.eagle.core.utilcode.util.*
import kotlinx.coroutines.*
import kotlinx.coroutines.Runnable
@Keep
@@ -12,60 +17,66 @@ import kotlinx.coroutines.Runnable
@Group("anr_fix")
class ANRFix {
@Insert
@TargetClass("com.zhidao.cosupload.service.UploadService")
@TargetMethod(methodName = "addUploadPaths")
private fun fixAddUploadPathsANR() {
ThreadUtils.getIoPool().execute(ANRFixTask(This.get(), "addUploadPaths"))
}
companion object {
@Insert
@TargetClass("com.zhidao.cosupload.service.UploadService")
@TargetMethod(methodName = "upload")
private fun fixUploadANR(@ClassOf("com.zhidao.cosupload.model.CacheUploadIdData") data: Any?) {
ThreadUtils.getIoPool().execute(ANRFixTask2(This.get(), "upload", data))
}
@Insert
@TargetClass("com.zhidao.cosupload.manager.CosUploadManagerImpl")
@TargetMethod(methodName = "upload")
private fun fixCosUploadManagerImplANR(productLine: String?, paths: List<String>?, eventId: String?, @ClassOf("com.zhidao.cosupload.DbPriorityConfig") config: Any?) {
ThreadUtils.getIoPool().execute(ANRFixTask3(This.get(), "upload", productLine, paths, eventId, config))
}
}
class ANRFixTask(private val delegate: Any, private val methodName: String): Runnable {
override fun run() {
delegate.javaClass.declaredMethods.find {
it.name != methodName && it.name.contains(methodName)
}?.also {
it.isAccessible = true
it.invoke(delegate)
@JvmStatic
@TargetClass(value = "android.os.Handler", scope = ALL)
@TargetMethod(methodName = "post")
@ReplaceInvoke
fun handlerPostProxy(handler: Handler, action: Runnable): Boolean {
val what = ObjectHashCodeUtils.getHashCodeIfNeed(action)
handler.removeMessages(what)
val msg = Message.obtain(handler, action)
msg.what = what
return handler.sendMessage(msg)
}
}
}
class ANRFixTask2(private val delegate: Any, private val methodName: String, private val p: Any?): Runnable {
override fun run() {
delegate.javaClass.declaredMethods.find {
it.name != methodName && it.name.contains(methodName)
}?.also {
it.isAccessible = true
it.invoke(delegate, p)
@JvmStatic
@TargetClass(value = "android.os.Handler", scope = ALL)
@TargetMethod(methodName = "postDelayed")
@ReplaceInvoke
fun handlerPostDelayProxy(handler: Handler, action: Runnable, delayMillis: Long): Boolean {
val what = ObjectHashCodeUtils.getHashCodeIfNeed(action)
handler.removeMessages(what)
val msg = Message.obtain(handler, action)
msg.what = what
return handler.sendMessageDelayed(msg, delayMillis)
}
}
}
class ANRFixTask3(private val delegate: Any, private val methodName: String,private val productLine: String?, private val paths: List<String>?, private val eventId: String?, private val config: Any?): Runnable {
@JvmStatic
@TargetClass(value = "android.app.Activity", scope = ALL)
@TargetMethod(methodName = "post")
@ReplaceInvoke
fun runOnUiThreadOfActivityProxy(activity: Activity, action: Runnable) {
if (Looper.myLooper() != Looper.getMainLooper()) {
UiThreadHandler.post(action)
} else {
activity.runOnUiThread(action)
}
}
override fun run() {
delegate.javaClass.declaredMethods.find {
it.name != methodName && it.name.contains(methodName)
}?.also {
it.isAccessible = true
it.invoke(delegate, productLine, paths, eventId, config)
@JvmStatic
@TargetClass(value = "android.view.View", scope = ALL)
@TargetMethod(methodName = "post")
@ReplaceInvoke
fun postOfViewProxy(view: View, action: Runnable): Boolean {
return if (Looper.myLooper() != Looper.getMainLooper()) {
UiThreadHandler.post(action)
} else {
view.post(action)
}
}
@JvmStatic
@TargetClass(value = "android.view.View", scope = ALL)
@TargetMethod(methodName = "postDelayed")
@ReplaceInvoke
fun postDelayedOfViewProxy(view: View, action: Runnable, delayMillis: Long): Boolean {
return if (Looper.myLooper() != Looper.getMainLooper()) {
UiThreadHandler.postDelayed(action, delayMillis)
} else {
view.postDelayed(action, delayMillis)
}
}
}
}

View File

@@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap
@Group("memory_leak")
class MemoryLeakFix {
@NameRegex("(com\\.mogo|com\\.zhidao|com\\.elegant|com\\.zhidaoauto|com\\.zhjt).*")
@NameRegex("(com\\.zhidao|com\\.elegant|com\\.zhidaoauto|com\\.zhjt|com\\.mogo(?!(\\.thread\\.ext|\\.launcher\\.lancet))).*")
@Insert(mayCreateSuper = true)
@ImplementedInterface("java.lang.Runnable", scope = LEAF)
@TargetMethod(methodName = "run")

View File

@@ -13,7 +13,7 @@ import com.knightboost.lancet.api.annotations.Weaver;
@Weaver
@Group("textview_opt")
public class TextViewSetTextOpt {
public class TextViewOpt {
@NameRegex("(com\\.mogo|com\\.zhidao|com\\.elegant|com\\.zhidaoauto|com\\.zhjt).*")
@TargetClass(value = "android.widget.TextView",scope = Scope.ALL)