提交 8628b72c 编写于 作者: J jackjintai

android:buildSrc module

上级 d02a2a67
...@@ -61,7 +61,6 @@ android { ...@@ -61,7 +61,6 @@ android {
} }
} }
...@@ -84,7 +83,7 @@ dokitExt { ...@@ -84,7 +83,7 @@ dokitExt {
slowMethod { slowMethod {
//0:默认模式 打印函数调用栈 需添加指定入口 默认为application onCreate 和attachBaseContext //0:默认模式 打印函数调用栈 需添加指定入口 默认为application onCreate 和attachBaseContext
//1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入 //1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入
strategy 0 strategy 1
//函数功能开关 //函数功能开关
methodSwitch true methodSwitch true
......
...@@ -13,7 +13,7 @@ buildscript { ...@@ -13,7 +13,7 @@ buildscript {
// } // }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.4.2' classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.novoda:bintray-release:0.9.2' classpath 'com.novoda:bintray-release:0.9.2'
// classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:${rootProject.ext.android["pluginVersionName"]}" // classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:${rootProject.ext.android["pluginVersionName"]}"
//classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.5" //classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.5"
......
...@@ -22,7 +22,7 @@ object DoKitExtUtil { ...@@ -22,7 +22,7 @@ object DoKitExtUtil {
private var mDokitPluginSwitch = true private var mDokitPluginSwitch = true
private var mDokitLogSwitch = false private var mDokitLogSwitch = false
private var mUsefulInRelease = false private var mUsefulInRelease = false
private val applications: MutableList<String> = mutableListOf() private val applications: MutableSet<String> = mutableSetOf()
var commExt = CommExt() var commExt = CommExt()
private set private set
val slowMethodExt = SlowMethodExt() val slowMethodExt = SlowMethodExt()
......
...@@ -48,7 +48,7 @@ open class SlowMethodExt( ...@@ -48,7 +48,7 @@ open class SlowMethodExt(
//默认阈值为5ms //默认阈值为5ms
var thresholdTime: Int = 5, var thresholdTime: Int = 5,
//入口函集合 //入口函集合
var enterMethods: MutableList<String> = mutableListOf()) { var enterMethods: MutableSet<String> = mutableSetOf()) {
/** /**
* 默认值为5ms * 默认值为5ms
*/ */
...@@ -56,7 +56,7 @@ open class SlowMethodExt( ...@@ -56,7 +56,7 @@ open class SlowMethodExt(
this.thresholdTime = thresholdTime this.thresholdTime = thresholdTime
} }
fun normalMethod(enterMethods: MutableList<String>) { fun normalMethod(enterMethods: MutableSet<String>) {
this.enterMethods = enterMethods this.enterMethods = enterMethods
} }
...@@ -72,9 +72,9 @@ open class SlowMethodExt( ...@@ -72,9 +72,9 @@ open class SlowMethodExt(
//默认阈值为500ms //默认阈值为500ms
var thresholdTime: Int = 500, var thresholdTime: Int = 500,
//普通函数的插装包名集合 //普通函数的插装包名集合
var packageNames: MutableList<String> = mutableListOf(), var packageNames: MutableSet<String> = mutableSetOf(),
//插桩黑名单 //插桩黑名单
var methodBlacklist: MutableList<String> = mutableListOf()) { var methodBlacklist: MutableSet<String> = mutableSetOf()) {
/** /**
* 默认值为500ms * 默认值为500ms
*/ */
...@@ -83,11 +83,11 @@ open class SlowMethodExt( ...@@ -83,11 +83,11 @@ open class SlowMethodExt(
this.thresholdTime = thresholdTime this.thresholdTime = thresholdTime
} }
fun packageNames(packageNames: MutableList<String>) { fun packageNames(packageNames: MutableSet<String>) {
this.packageNames = packageNames this.packageNames = packageNames
} }
fun methodBlacklist(methodBlacklist: MutableList<String>) { fun methodBlacklist(methodBlacklist: MutableSet<String>) {
this.methodBlacklist = methodBlacklist this.methodBlacklist = methodBlacklist
} }
......
package com.didichuxing.doraemonkit.plugin.transform
import com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import com.didichuxing.doraemonkit.plugin.methodExitInsnNode
import com.didiglobal.booster.annotations.Priority
import com.didiglobal.booster.transform.TransformContext
import com.didiglobal.booster.transform.asm.ClassTransformer
import com.didiglobal.booster.transform.asm.className
import com.google.auto.service.AutoService
import org.objectweb.asm.Opcodes.*
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.InsnList
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/14-18:07
* 描 述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
* 修订历史:
* ================================================
*/
@Priority(2)
@AutoService(ClassTransformer::class)
class BigImgTransformer : ClassTransformer {
private val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil"
private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;"
override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
if (!DoKitExtUtil.dokitPluginSwitchOpen()) {
return klass
}
if (!DoKitExtUtil.commExt.bigImgSwitch) {
return klass
}
if (DoKitExtUtil.ignorePackageNames(klass.className)) {
return klass
}
val className = klass.className
//glide
if (className == "com.bumptech.glide.request.SingleRequest") {
klass.methods.find { methodNode ->
(methodNode.name == "init" || methodNode.name == "<init>") && methodNode.desc != null
}.let { methodNode ->
//函数结束的地方插入
methodNode?.instructions?.methodExitInsnNode().let {
methodNode?.instructions?.insertBefore(it, createGlideInsnList())
}
}
}
//picasso
if (className == "com.squareup.picasso.Request") {
klass.methods.find { methodNode ->
methodNode.name == "<init>" && methodNode.desc != null
}.let { methodNode ->
//函数结束的地方插入
methodNode?.instructions?.methodExitInsnNode().let {
methodNode?.instructions?.insertBefore(it, createPicassoInsnList())
}
}
}
//Fresco
if (className == "com.facebook.imagepipeline.request.ImageRequest") {
klass.methods.find { methodNode ->
methodNode.name == "<init>" && methodNode.desc != null
}.let { methodNode ->
//函数开始的地方插入
methodNode?.instructions?.insert(createFrescoInsnList())
}
}
//ImageLoader
if (className == "com.nostra13.universalimageloader.core.ImageLoadingInfo") {
klass.methods.find { methodNode ->
methodNode.name == "<init>" && methodNode.desc != null
}.let { methodNode ->
methodNode?.instructions?.insert(createImageLoaderInsnList())
}
}
return klass
}
/**
* 创建Glide Aop代码指令
*/
private fun createGlideInsnList(): InsnList {
val insnList = InsnList()
insnList.add(VarInsnNode(ALOAD, 0))
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/glide/GlideHook", "proxy", "(Ljava/lang/Object;)V", false))
return insnList
}
/**
* 创建Picasso Aop代码指令
*/
private fun createPicassoInsnList(): InsnList {
val insnList = InsnList()
insnList.add(VarInsnNode(ALOAD, 0))
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/picasso/PicassoHook", "proxy", "(Ljava/lang/Object;)V", false))
return insnList
}
/**
* 创建Fresco Aop代码指令
*/
private fun createFrescoInsnList(): InsnList {
val insnList = InsnList()
insnList.add(VarInsnNode(ALOAD, 1))
insnList.add(VarInsnNode(ALOAD, 1))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getSourceUri", "()Landroid/net/Uri;", false))
insnList.add(VarInsnNode(ALOAD, 1))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "getPostprocessor", "()Lcom/facebook/imagepipeline/request/Postprocessor;", false))
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/fresco/FrescoHook", "proxy", "(Landroid/net/Uri;Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/Postprocessor;", false))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/facebook/imagepipeline/request/ImageRequestBuilder", "setPostprocessor", "(Lcom/facebook/imagepipeline/request/Postprocessor;)Lcom/facebook/imagepipeline/request/ImageRequestBuilder;", false))
return insnList
}
/**
* 创建ImageLoader Aop代码指令
*/
private fun createImageLoaderInsnList(): InsnList {
val insnList = InsnList()
insnList.add(VarInsnNode(ALOAD, 6))
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/bigimg/imageloader/ImageLoaderHook", "proxy", "(Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;)Lcom/nostra13/universalimageloader/core/listener/ImageLoadingListener;", false))
insnList.add(VarInsnNode(ASTORE, 6))
return insnList
}
}
package com.didichuxing.doraemonkit.plugin.transform
import com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import com.didichuxing.doraemonkit.plugin.methodExitInsnNode
import com.didiglobal.booster.annotations.Priority
import com.didiglobal.booster.transform.TransformContext
import com.didiglobal.booster.transform.asm.ClassTransformer
import com.didiglobal.booster.transform.asm.asIterable
import com.didiglobal.booster.transform.asm.className
import com.google.auto.service.AutoService
import org.objectweb.asm.Opcodes.*
import org.objectweb.asm.tree.*
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/14-18:07
* 描 述:全局业务代码 慢函数 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
* 修订历史:
* ================================================
*/
@Priority(3)
@AutoService(ClassTransformer::class)
class GlobalSlowMethodTransformer : ClassTransformer {
val thresholdTime = DoKitExtUtil.slowMethodExt.normalMethod.thresholdTime
override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
if (!DoKitExtUtil.dokitPluginSwitchOpen()) {
return klass
}
if (!DoKitExtUtil.slowMethodExt.methodSwitch) {
return klass
}
if (DoKitExtUtil.slowMethodExt.strategy == SlowMethodExt.STRATEGY_STACK) {
return klass
}
if (DoKitExtUtil.ignorePackageNames(klass.className)) {
return klass
}
val className = klass.className
//没有自定义设置插装包名 默认是以applicationId为包名 即全局业务代码插桩
DoKitExtUtil.slowMethodExt.normalMethod.packageNames.forEach { packageName ->
//包含在白名单中且不在黑名单中
if (className.contains(packageName) && notMatchedBlackList(className)) {
klass.methods.filter { methodNode ->
methodNode.name != "<init>"
}.forEach { methodNode ->
methodNode.instructions.asIterable().filterIsInstance(MethodInsnNode::class.java).let { methodInsnNodes ->
if (methodInsnNodes.isNotEmpty()) {
//方法入口插入
methodNode.instructions.insert(createMethodEnterInsnList(className, methodNode.name, methodNode.access))
//方法出口插入
methodNode.instructions.methodExitInsnNode().let { methodExitInsnNode ->
methodNode.instructions.insertBefore(methodExitInsnNode, createMethodExitInsnList(className, methodNode.name, methodNode.access))
}
}
}
}
}
}
return klass
}
private fun notMatchedBlackList(className: String): Boolean {
for (strBlack in DoKitExtUtil.slowMethodExt.normalMethod.methodBlacklist) {
if (className.contains(strBlack)) {
return false
}
}
return true
}
/**
* 创建慢函数入口指令集
*/
private fun createMethodEnterInsnList(className: String, methodName: String, access: Int): InsnList {
val isStaticMethod = access and ACC_STATIC != 0
val insnList = InsnList()
if (isStaticMethod) {
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false))
insnList.add(IntInsnNode(SIPUSH, thresholdTime))
insnList.add(LdcInsnNode("$className&$methodName"))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostStart", "(ILjava/lang/String;)V", false))
} else {
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false))
insnList.add(IntInsnNode(SIPUSH, thresholdTime))
insnList.add(LdcInsnNode("$className&$methodName"))
insnList.add(VarInsnNode(ALOAD, 0))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostStart", "(ILjava/lang/String;Ljava/lang/Object;)V", false))
}
return insnList
}
/**
* 创建慢函数退出时的指令集
*/
private fun createMethodExitInsnList(className: String, methodName: String, access: Int): InsnList {
val isStaticMethod = access and ACC_STATIC != 0
val insnList = InsnList()
if (isStaticMethod) {
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false))
insnList.add(IntInsnNode(SIPUSH, thresholdTime))
insnList.add(LdcInsnNode("$className&$methodName"))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeStaticMethodCostEnd", "(ILjava/lang/String;)V", false))
} else {
insnList.add(MethodInsnNode(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "getInstance", "()Lcom/didichuxing/doraemonkit/aop/MethodCostUtil;", false))
insnList.add(IntInsnNode(SIPUSH, thresholdTime))
insnList.add(LdcInsnNode("$className&$methodName"))
insnList.add(VarInsnNode(ALOAD, 0))
insnList.add(MethodInsnNode(INVOKEVIRTUAL, "com/didichuxing/doraemonkit/aop/MethodCostUtil", "recodeObjectMethodCostEnd", "(ILjava/lang/String;Ljava/lang/Object;)V", false))
}
return insnList
}
}
...@@ -3,8 +3,6 @@ package com.didichuxing.doraemonkit.plugin.transform ...@@ -3,8 +3,6 @@ package com.didichuxing.doraemonkit.plugin.transform
import com.didichuxing.doraemonkit.plugin.DoKitExtUtil import com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import com.didiglobal.booster.annotations.Priority import com.didiglobal.booster.annotations.Priority
import com.didiglobal.booster.kotlinx.asIterable import com.didiglobal.booster.kotlinx.asIterable
import com.didiglobal.booster.kotlinx.file
import com.didiglobal.booster.kotlinx.touch
import com.didiglobal.booster.transform.TransformContext import com.didiglobal.booster.transform.TransformContext
import com.didiglobal.booster.transform.asm.ClassTransformer import com.didiglobal.booster.transform.asm.ClassTransformer
import com.didiglobal.booster.transform.asm.className import com.didiglobal.booster.transform.asm.className
...@@ -13,8 +11,6 @@ import org.objectweb.asm.Opcodes.INVOKESTATIC ...@@ -13,8 +11,6 @@ import org.objectweb.asm.Opcodes.INVOKESTATIC
import org.objectweb.asm.Opcodes.INVOKEVIRTUAL import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodInsnNode import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.MethodNode
import java.io.PrintWriter
/** /**
* ================================================ * ================================================
...@@ -28,19 +24,22 @@ import java.io.PrintWriter ...@@ -28,19 +24,22 @@ import java.io.PrintWriter
@Priority(1) @Priority(1)
@AutoService(ClassTransformer::class) @AutoService(ClassTransformer::class)
class UrlConnectionTransformer : ClassTransformer { class UrlConnectionTransformer : ClassTransformer {
private val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil"
private val DESC = "(Ljava/net/URLConnection;)Ljava/net/URLConnection;"
override fun transform(context: TransformContext, klass: ClassNode): ClassNode { override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
if (!DoKitExtUtil.dokitPluginSwitchOpen()) { if (!DoKitExtUtil.dokitPluginSwitchOpen()) {
return klass return klass
} }
if (DoKitExtUtil.ignorePackageNames(klass.className)) { if (!DoKitExtUtil.commExt.networkSwitch) {
return klass return klass
} }
if (DoKitExtUtil.ignorePackageNames(klass.className)) {
return klass
}
if (DoKitExtUtil.commExt.networkSwitch) {
klass.methods.forEach { method -> klass.methods.forEach { method ->
method.instructions?.iterator()?.asIterable()?.filterIsInstance(MethodInsnNode::class.java)?.filter { method.instructions?.iterator()?.asIterable()?.filterIsInstance(MethodInsnNode::class.java)?.filter {
it.opcode == INVOKEVIRTUAL && it.opcode == INVOKEVIRTUAL &&
...@@ -48,13 +47,13 @@ class UrlConnectionTransformer : ClassTransformer { ...@@ -48,13 +47,13 @@ class UrlConnectionTransformer : ClassTransformer {
it.name == "openConnection" && it.name == "openConnection" &&
it.desc == "()Ljava/net/URLConnection;" it.desc == "()Ljava/net/URLConnection;"
}?.forEach { }?.forEach {
method.instructions.insert(it, MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", "(Ljava/net/URLConnection;)Ljava/net/URLConnection;", false)) method.instructions.insert(it, MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", DESC, false))
}
} }
} }
return klass return klass
} }
}
private const val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil"
}
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply from: 'upload.gradle' apply from: 'upload.gradle'
android { android {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册