Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
DoraemonKit
提交
8628b72c
D
DoraemonKit
项目概览
DiDi
/
DoraemonKit
11 个月 前同步成功
通知
166
Star
19623
Fork
3062
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
DoraemonKit
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8628b72c
编写于
5月 20, 2020
作者:
J
jackjintai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
android:buildSrc module
上级
d02a2a67
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
297 addition
and
28 deletion
+297
-28
Android/app/build.gradle
Android/app/build.gradle
+1
-2
Android/build.gradle
Android/build.gradle
+1
-1
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
...kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
+1
-1
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
...didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
+6
-6
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/BigImgTransformer.kt
...chuxing/doraemonkit/plugin/transform/BigImgTransformer.kt
+143
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/GlobalSlowMethodTransformer.kt
...raemonkit/plugin/transform/GlobalSlowMethodTransformer.kt
+127
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/UrlConnectionTransformer.kt
.../doraemonkit/plugin/transform/UrlConnectionTransformer.kt
+17
-18
Android/doraemonkit/build.gradle
Android/doraemonkit/build.gradle
+1
-0
未找到文件。
Android/app/build.gradle
浏览文件 @
8628b72c
...
...
@@ -61,7 +61,6 @@ android {
}
}
...
...
@@ -84,7 +83,7 @@ dokitExt {
slowMethod
{
//0:默认模式 打印函数调用栈 需添加指定入口 默认为application onCreate 和attachBaseContext
//1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入
strategy
0
strategy
1
//函数功能开关
methodSwitch
true
...
...
Android/build.gradle
浏览文件 @
8628b72c
...
...
@@ -13,7 +13,7 @@ buildscript {
// }
}
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.didichuxing.doraemonkit:doraemonkit-plugin:${rootProject.ext.android["pluginVersionName"]}"
//classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.5"
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
浏览文件 @
8628b72c
...
...
@@ -22,7 +22,7 @@ object DoKitExtUtil {
private
var
mDokitPluginSwitch
=
true
private
var
mDokitLogSwitch
=
false
private
var
mUsefulInRelease
=
false
private
val
applications
:
Mutable
List
<
String
>
=
mutableLis
tOf
()
private
val
applications
:
Mutable
Set
<
String
>
=
mutableSe
tOf
()
var
commExt
=
CommExt
()
private
set
val
slowMethodExt
=
SlowMethodExt
()
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
浏览文件 @
8628b72c
...
...
@@ -48,7 +48,7 @@ open class SlowMethodExt(
//默认阈值为5ms
var
thresholdTime
:
Int
=
5
,
//入口函集合
var
enterMethods
:
Mutable
List
<
String
>
=
mutableLis
tOf
())
{
var
enterMethods
:
Mutable
Set
<
String
>
=
mutableSe
tOf
())
{
/**
* 默认值为5ms
*/
...
...
@@ -56,7 +56,7 @@ open class SlowMethodExt(
this
.
thresholdTime
=
thresholdTime
}
fun
normalMethod
(
enterMethods
:
Mutable
Lis
t
<
String
>)
{
fun
normalMethod
(
enterMethods
:
Mutable
Se
t
<
String
>)
{
this
.
enterMethods
=
enterMethods
}
...
...
@@ -72,9 +72,9 @@ open class SlowMethodExt(
//默认阈值为500ms
var
thresholdTime
:
Int
=
500
,
//普通函数的插装包名集合
var
packageNames
:
Mutable
List
<
String
>
=
mutableLis
tOf
(),
var
packageNames
:
Mutable
Set
<
String
>
=
mutableSe
tOf
(),
//插桩黑名单
var
methodBlacklist
:
Mutable
List
<
String
>
=
mutableLis
tOf
())
{
var
methodBlacklist
:
Mutable
Set
<
String
>
=
mutableSe
tOf
())
{
/**
* 默认值为500ms
*/
...
...
@@ -83,11 +83,11 @@ open class SlowMethodExt(
this
.
thresholdTime
=
thresholdTime
}
fun
packageNames
(
packageNames
:
Mutable
Lis
t
<
String
>)
{
fun
packageNames
(
packageNames
:
Mutable
Se
t
<
String
>)
{
this
.
packageNames
=
packageNames
}
fun
methodBlacklist
(
methodBlacklist
:
Mutable
Lis
t
<
String
>)
{
fun
methodBlacklist
(
methodBlacklist
:
Mutable
Se
t
<
String
>)
{
this
.
methodBlacklist
=
methodBlacklist
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/BigImgTransformer.kt
0 → 100644
浏览文件 @
8628b72c
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
}
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/GlobalSlowMethodTransformer.kt
0 → 100644
浏览文件 @
8628b72c
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
}
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/UrlConnectionTransformer.kt
浏览文件 @
8628b72c
...
...
@@ -3,8 +3,6 @@ package com.didichuxing.doraemonkit.plugin.transform
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didiglobal.booster.annotations.Priority
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.asm.ClassTransformer
import
com.didiglobal.booster.transform.asm.className
...
...
@@ -13,8 +11,6 @@ import org.objectweb.asm.Opcodes.INVOKESTATIC
import
org.objectweb.asm.Opcodes.INVOKEVIRTUAL
import
org.objectweb.asm.tree.ClassNode
import
org.objectweb.asm.tree.MethodInsnNode
import
org.objectweb.asm.tree.MethodNode
import
java.io.PrintWriter
/**
* ================================================
...
...
@@ -28,19 +24,22 @@ import java.io.PrintWriter
@Priority
(
1
)
@AutoService
(
ClassTransformer
::
class
)
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
{
if
(!
DoKitExtUtil
.
dokitPluginSwitchOpen
())
{
return
klass
}
if
(
DoKitExtUtil
.
ignorePackageNames
(
klass
.
className
)
)
{
if
(
!
DoKitExtUtil
.
commExt
.
networkSwitch
)
{
return
klass
}
if
(
DoKitExtUtil
.
ignorePackageNames
(
klass
.
className
))
{
return
klass
}
if
(
DoKitExtUtil
.
commExt
.
networkSwitch
)
{
klass
.
methods
.
forEach
{
method
->
method
.
instructions
?.
iterator
()
?.
asIterable
()
?.
filterIsInstance
(
MethodInsnNode
::
class
.
java
)
?.
filter
{
it
.
opcode
==
INVOKEVIRTUAL
&&
...
...
@@ -48,13 +47,13 @@ class UrlConnectionTransformer : ClassTransformer {
it
.
name
==
"openConnection"
&&
it
.
desc
==
"()Ljava/net/URLConnection;"
}
?.
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
}
}
private
const
val
SHADOW_URL
=
"com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil"
}
Android/doraemonkit/build.gradle
浏览文件 @
8628b72c
apply
plugin:
'com.android.library'
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-kapt'
apply
from:
'upload.gradle'
android
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录