Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
DoraemonKit
提交
28b07296
D
DoraemonKit
项目概览
DiDi
/
DoraemonKit
10 个月 前同步成功
通知
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,体验更适合开发者的 AI 搜索 >>
提交
28b07296
编写于
5月 22, 2020
作者:
J
jackjintai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
android:完成函数调用栈n级调用(用户自定义)
上级
8628b72c
变更
46
隐藏空白更改
内联
并排
Showing
46 changed file
with
683 addition
and
199 deletion
+683
-199
Android/app/build.gradle
Android/app/build.gradle
+4
-3
Android/app/doraemonkit.gradle
Android/app/doraemonkit.gradle
+1
-1
Android/app/src/debug/java/com/didichuxing/doraemondemo/App.kt
...id/app/src/debug/java/com/didichuxing/doraemondemo/App.kt
+2
-2
Android/app/src/debug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
...ug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
+5
-15
Android/app/src/main/java/com/didichuxing/doraemondemo/AopTest.java
...p/src/main/java/com/didichuxing/doraemondemo/AopTest.java
+3
-8
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt
...ain/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt
+8
-3
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
...kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
+9
-7
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
.../kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
+24
-2
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt
...idichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt
+2
-1
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmclasstransformer/BaseDoKitClassTransformer.kt
...t/plugin/asmclasstransformer/BaseDoKitClassTransformer.kt
+15
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmclasstransformer/MethodStackDepTransformer.kt
...t/plugin/asmclasstransformer/MethodStackDepTransformer.kt
+138
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt
...aemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt
+82
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt
.../doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt
+17
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/BigImgTransformer.kt
.../doraemonkit/plugin/classtransformer/BigImgTransformer.kt
+10
-8
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/CommTransformer.kt
...ng/doraemonkit/plugin/classtransformer/CommTransformer.kt
+17
-10
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMethodStackTransformer.kt
...it/plugin/classtransformer/EnterMethodStackTransformer.kt
+162
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/GlobalSlowMethodTransformer.kt
...it/plugin/classtransformer/GlobalSlowMethodTransformer.kt
+8
-4
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/UrlConnectionTransformer.kt
...onkit/plugin/classtransformer/UrlConnectionTransformer.kt
+4
-1
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt
.../com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt
+1
-5
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
...didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
+4
-4
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt
...oraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt
+3
-3
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNode.kt
...huxing/doraemonkit/plugin/stack_method/MethodStackNode.kt
+18
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt
...ng/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt
+30
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt
...huxing/doraemonkit/plugin/transform/DoKitBaseTransform.kt
+6
-5
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt
...huxing/doraemonkit/plugin/transform/DoKitCommTransform.kt
+12
-0
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt
...xing/doraemonkit/plugin/transform/DoKitDependTransform.kt
+19
-0
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/DoKitPlugin.java
...roovy/com/didichuxing/doraemonkit/plugin/DoKitPlugin.java
+9
-9
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitBigImageTransform.java
.../doraemonkit/plugin/transform/DokitBigImageTransform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitCommTransform.java
...xing/doraemonkit/plugin/transform/DokitCommTransform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack0Transform.java
...aemonkit/plugin/transform/DokitMethodStack0Transform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack1Transform.java
...aemonkit/plugin/transform/DokitMethodStack1Transform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack2Transform.java
...aemonkit/plugin/transform/DokitMethodStack2Transform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack3Transform.java
...aemonkit/plugin/transform/DokitMethodStack3Transform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack4Transform.java
...aemonkit/plugin/transform/DokitMethodStack4Transform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitSlowMethodTransform.java
...oraemonkit/plugin/transform/DokitSlowMethodTransform.java
+1
-1
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitUrlConnectionTransform.java
...emonkit/plugin/transform/DokitUrlConnectionTransform.java
+1
-1
Android/doraemonkit/build.gradle
Android/doraemonkit/build.gradle
+1
-1
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/DoraemonKitReal.kt
.../main/java/com/didichuxing/doraemonkit/DoraemonKitReal.kt
+3
-2
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil.java
...chuxing/doraemonkit/aop/method_stack/MethodStackUtil.java
+48
-89
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitManagerAdapter.kt
...ichuxing/doraemonkit/kit/toolpanel/DokitManagerAdapter.kt
+1
-1
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitManagerFragment.kt
...chuxing/doraemonkit/kit/toolpanel/DokitManagerFragment.kt
+1
-1
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitSettingAdapter.kt
...ichuxing/doraemonkit/kit/toolpanel/DokitSettingAdapter.kt
+1
-1
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitSettingFragment.kt
...chuxing/doraemonkit/kit/toolpanel/DokitSettingFragment.kt
+1
-1
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/ToolPanelAdapter.kt
...didichuxing/doraemonkit/kit/toolpanel/ToolPanelAdapter.kt
+2
-2
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/ToolPanelDokitView.kt
...dichuxing/doraemonkit/kit/toolpanel/ToolPanelDokitView.kt
+1
-1
Android/gradle.properties
Android/gradle.properties
+2
-0
未找到文件。
Android/app/build.gradle
浏览文件 @
28b07296
apply
plugin:
'com.android.application'
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-kapt'
apply
from:
'doraemonkit.gradle'
android
{
...
...
@@ -73,7 +74,7 @@ dokitExt {
//通用设置
comm
{
//地图经纬度开关
gpsSwitch
tru
e
gpsSwitch
fals
e
//网络开关
networkSwitch
true
//大图开关
...
...
@@ -83,14 +84,14 @@ dokitExt {
slowMethod
{
//0:默认模式 打印函数调用栈 需添加指定入口 默认为application onCreate 和attachBaseContext
//1:普通模式 运行时打印某个函数的耗时 全局业务代码函数插入
strategy
1
strategy
0
//函数功能开关
methodSwitch
true
//调用栈模式配置
stackMethod
{
//默认值为 5ms 小于该值的函数在调用栈中不显示
thresholdTime
10
thresholdTime
5
//调用栈函数入口
enterMethods
=
[
"com.didichuxing.doraemondemo.MainDebugActivity.test1"
]
}
...
...
Android/app/doraemonkit.gradle
浏览文件 @
28b07296
...
...
@@ -5,7 +5,7 @@ if (rootProject.ext.config["applyPlugin"]) {
dependencies
{
//外部平台依赖
debugImplementation
project
(
":doraemonkit"
)
debugImplementation
project
(
":doraemonkit-weex"
)
//
debugImplementation project(":doraemonkit-weex")
// releaseImplementation project(":doraemonkit-no-op")
// debugImplementation project(":doraemonkit-leakcanary")
//新版线上包
...
...
Android/app/src/debug/java/com/didichuxing/doraemondemo/App.kt
浏览文件 @
28b07296
...
...
@@ -32,8 +32,8 @@ class App : Application() {
// kits.add(DemoKit())
// kits.add(DemoKit())
val
mapKits
:
LinkedHashMap
<
String
,
MutableList
<
AbstractKit
>>
=
linkedMapOf
()
mapKits
.
put
(
"业务专区1"
,
mutableListOf
(
DemoKit
()
))
mapKits
.
put
(
"业务专区2"
,
mutableListOf
(
DemoKit
()
))
mapKits
[
"业务专区1"
]
=
mutableListOf
<
AbstractKit
>(
DemoKit
(
))
mapKits
[
"业务专区2"
]
=
mutableListOf
<
AbstractKit
>(
DemoKit
(
))
DoraemonKit
.
install
(
this
,
mapKits
=
mapKits
,
productId
=
"749a0600b5e48dd77cf8ee680be7b1b7"
)
val
config
=
ImagePipelineConfig
.
newBuilder
(
this
)
...
...
Android/app/src/debug/java/com/didichuxing/doraemondemo/MainDebugActivity.kt
浏览文件 @
28b07296
...
...
@@ -25,24 +25,19 @@ import com.baidu.location.BDAbstractLocationListener
import
com.baidu.location.BDLocation
import
com.baidu.location.LocationClient
import
com.baidu.location.LocationClientOption
import
com.blankj.utilcode.util.*
import
com.blankj.utilcode.util.ConvertUtils
import
com.blankj.utilcode.util.ThreadUtils
import
com.blankj.utilcode.util.ThreadUtils.SimpleTask
import
com.bumptech.glide.Glide
import
com.bumptech.glide.load.engine.DiskCacheStrategy
import
com.bumptech.glide.load.resource.bitmap.CircleCrop
import
com.didichuxing.doraemondemo.retrofit.GithubService
import
com.didichuxing.doraemonkit.DoraemonKit
import
com.didichuxing.doraemonkit.aop.method_stack.MethodInvokNode
import
com.didichuxing.doraemonkit.aop.method_stack.MethodStackBean
import
com.didichuxing.doraemonkit.aop.method_stack.MethodStackUtil
import
com.didichuxing.doraemonkit.okgo.DokitOkGo
import
com.didichuxing.doraemonkit.okgo.callback.StringCallback
import
com.didichuxing.doraemonkit.okgo.model.Response
import
com.facebook.drawee.backends.pipeline.Fresco
import
com.facebook.drawee.view.SimpleDraweeView
import
com.google.gson.Gson
import
com.google.gson.GsonBuilder
import
com.google.gson.JsonObject
import
com.nostra13.universalimageloader.core.ImageLoader
import
com.nostra13.universalimageloader.core.ImageLoaderConfiguration
import
com.squareup.picasso.MemoryPolicy
...
...
@@ -54,7 +49,6 @@ import com.tencent.map.geolocation.TencentLocationRequest
import
io.reactivex.schedulers.Schedulers
import
kotlinx.android.synthetic.main.activity_main.*
import
okhttp3.*
import
org.json.JSONArray
import
org.json.JSONObject
import
pub.devrel.easypermissions.EasyPermissions
import
pub.devrel.easypermissions.PermissionRequest
...
...
@@ -62,9 +56,7 @@ import retrofit2.Retrofit
import
retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import
retrofit2.converter.gson.GsonConverterFactory
import
java.io.*
import
java.lang.reflect.Type
import
java.net.*
import
java.util.ArrayList
/**
* @author jintai
...
...
@@ -198,10 +190,8 @@ class MainDebugActivity : BaseActivity(), View.OnClickListener {
private
val
mLocationListener
:
LocationListener
=
object
:
LocationListener
{
override
fun
onLocationChanged
(
location
:
Location
)
{
if
(
location
!=
null
)
{
val
string
=
"lat====>"
+
location
.
latitude
+
" lng====>"
+
location
.
longitude
Log
.
i
(
TAG
,
"系统定位====>$string"
)
}
val
string
=
"lat====>"
+
location
.
latitude
+
" lng====>"
+
location
.
longitude
Log
.
i
(
TAG
,
"系统定位====>$string"
)
}
override
fun
onProviderDisabled
(
arg0
:
String
)
{}
...
...
@@ -440,7 +430,7 @@ class MainDebugActivity : BaseActivity(), View.OnClickListener {
.
url
(
"http://cdn1.lbesec.com/products/history/20131220/privacyspace_rel_2.2.1617.apk"
)
.
build
()
}
val
call
=
okHttpClient
!!
.
newCall
(
request
)
val
call
=
okHttpClient
!!
.
newCall
(
request
!!
)
val
startTime
=
SystemClock
.
uptimeMillis
()
call
.
enqueue
(
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
...
...
Android/app/src/main/java/com/didichuxing/doraemondemo/AopTest.java
浏览文件 @
28b07296
...
...
@@ -3,6 +3,7 @@ package com.didichuxing.doraemondemo;
import
android.util.Log
;
import
com.didichuxing.doraemonkit.aop.DokitPluginConfig
;
import
com.didichuxing.doraemonkit.aop.method_stack.MethodStackUtil
;
import
com.didichuxing.doraemonkit.aop.urlconnection.HttpUrlConnectionProxyUtil
;
import
java.io.IOException
;
...
...
@@ -25,14 +26,8 @@ public class AopTest {
private
static
final
String
TAG
=
"AopTest"
;
public
void
test
()
{
try
{
URL
url
=
new
URL
(
"sss"
);
URLConnection
connection
=
url
.
openConnection
();
connection
.
setReadTimeout
(
1000
);
connection
.
connect
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
//MethodStackUtil.getInstance().recodeObjectMethodCostStart(10, 5, 0, "AopTest", "test", "desc", this);
MethodStackUtil
.
getInstance
().
recodeStaticMethodCostStart
(
10
,
5
,
7
,
"AopTest"
,
"test"
,
"desc"
);
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExt.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin
import
org.objectweb.asm.Opcodes.*
import
org.objectweb.asm.tree.ClassNode
import
org.objectweb.asm.tree.InsnList
import
org.objectweb.asm.tree.InsnNode
import
org.objectweb.asm.tree.MethodInsnNode
/**
* ================================================
...
...
@@ -14,8 +16,8 @@ import org.objectweb.asm.tree.InsnNode
* ================================================
*/
fun
InsnList
.
methodExitInsnNode
():
InsnNode
?
{
return
this
.
iterator
()
?.
asSequence
()
?.
filterIsInstance
(
InsnNode
::
class
.
java
)
?.
fi
nd
{
fun
InsnList
.
getMethodExitInsnNodes
():
Sequence
<
InsnNode
>
?
{
return
this
.
iterator
()
?.
asSequence
()
?.
filterIsInstance
(
InsnNode
::
class
.
java
)
?.
fi
lter
{
it
.
opcode
==
RETURN
||
it
.
opcode
==
IRETURN
||
it
.
opcode
==
FRETURN
||
...
...
@@ -24,4 +26,7 @@ fun InsnList.methodExitInsnNode(): InsnNode? {
it
.
opcode
==
DRETURN
||
it
.
opcode
==
ATHROW
}
}
\ No newline at end of file
}
val
MethodInsnNode
.
ownerClassName
:
String
get
()
=
owner
.
replace
(
'/'
,
'.'
)
\ No newline at end of file
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitExtUtil.kt
浏览文件 @
28b07296
...
...
@@ -3,6 +3,8 @@ package com.didichuxing.doraemonkit.plugin
import
com.didichuxing.doraemonkit.plugin.extension.CommExt
import
com.didichuxing.doraemonkit.plugin.extension.DoKitExt
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt.Companion.STRATEGY_NORMAL
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil
/**
* ================================================
...
...
@@ -21,7 +23,11 @@ object DoKitExtUtil {
*/
private
var
mDokitPluginSwitch
=
true
private
var
mDokitLogSwitch
=
false
private
var
mUsefulInRelease
=
false
/**
* 默认函数调用为5级
*/
public
var
mStackMethodLevel
=
5
private
val
applications
:
MutableSet
<
String
>
=
mutableSetOf
()
var
commExt
=
CommExt
()
private
set
...
...
@@ -35,11 +41,6 @@ object DoKitExtUtil {
return
mDokitLogSwitch
}
fun
usefulInRelease
():
Boolean
{
return
mUsefulInRelease
}
/**
* 初始化
*
...
...
@@ -49,7 +50,6 @@ object DoKitExtUtil {
fun
init
(
dokitEx
:
DoKitExt
,
applicationId
:
String
)
{
mDokitPluginSwitch
=
dokitEx
.
dokitPluginSwitch
mDokitLogSwitch
=
dokitEx
.
dokitLogSwitch
mUsefulInRelease
=
dokitEx
.
usefulInRelease
//设置普通的配置
commExt
=
dokitEx
.
comm
slowMethodExt
.
strategy
=
dokitEx
.
slowMethod
.
strategy
...
...
@@ -97,8 +97,10 @@ object DoKitExtUtil {
/**
* ============慢函数stack策略的配置 end==========
*/
}
fun
setApplications
(
applications
:
MutableSet
<
String
>)
{
if
(
applications
.
isEmpty
())
{
return
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitPlugin.kt
浏览文件 @
28b07296
...
...
@@ -3,8 +3,11 @@ package com.didichuxing.doraemonkit.plugin
import
com.android.build.gradle.AppExtension
import
com.android.build.gradle.LibraryExtension
import
com.didichuxing.doraemonkit.plugin.extension.DoKitExt
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil
import
com.didichuxing.doraemonkit.plugin.transform.*
import
com.didiglobal.booster.annotations.Priority
import
com.didiglobal.booster.gradle.getAndroid
import
com.didiglobal.booster.gradle.getProperty
import
com.didiglobal.booster.task.spi.VariantProcessor
import
org.gradle.api.Plugin
import
org.gradle.api.Project
...
...
@@ -25,6 +28,13 @@ class DoKitPlugin : Plugin<Project> {
//创建指定扩展 并将project 传入构造函数
project
.
extensions
.
create
(
"dokitExt"
,
DoKitExt
::
class
.
java
)
// val debug = project.gradle.startParameter.taskNames.any {
// it.contains("debug") || it.contains("Debug")
// }
// if (!debug) {
// return
// }
project
.
gradle
.
addListener
(
DoKitTransformTaskExecutionListener
(
project
))
//println("project.plugins===>${project.plugins}")
...
...
@@ -68,8 +78,20 @@ class DoKitPlugin : Plugin<Project> {
when
{
project
.
plugins
.
hasPlugin
(
"com.android.application"
)
||
project
.
plugins
.
hasPlugin
(
"com.android.dynamic-feature"
)
->
{
project
.
getAndroid
<
AppExtension
>().
let
{
androidExt
->
val
methodStackLevel
=
project
.
getProperty
(
"DoKit_MethodStack_Level"
,
5
)
DoKitExtUtil
.
mStackMethodLevel
=
methodStackLevel
MethodStackNodeUtil
.
METHOD_STACK_KEYS
.
clear
()
//注册transform
androidExt
.
registerTransform
(
DoKitTransform
(
project
))
androidExt
.
registerTransform
(
DoKitCommTransform
(
project
))
MethodStackNodeUtil
.
METHOD_STACK_KEYS
.
add
(
0
,
mutableSetOf
<
String
>())
val
methodStackRange
=
1
until
methodStackLevel
if
(
methodStackLevel
>
1
)
{
for
(
index
in
methodStackRange
)
{
MethodStackNodeUtil
.
METHOD_STACK_KEYS
.
add
(
index
,
mutableSetOf
<
String
>())
androidExt
.
registerTransform
(
DoKitDependTransform
(
project
,
index
))
}
}
//项目评估完毕回调
project
.
afterEvaluate
{
this
.
variantProcessors
.
let
{
processors
->
...
...
@@ -85,7 +107,7 @@ class DoKitPlugin : Plugin<Project> {
project
.
plugins
.
hasPlugin
(
"com.android.library"
)
->
{
project
.
getAndroid
<
LibraryExtension
>().
let
{
libraryExt
->
libraryExt
.
registerTransform
(
DoKitTransform
(
project
))
libraryExt
.
registerTransform
(
DoKit
Comm
Transform
(
project
))
project
.
afterEvaluate
{
this
.
variantProcessors
.
let
{
processors
->
libraryExt
.
libraryVariants
.
forEach
{
variant
->
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/DoKitTransformInvocation.kt
浏览文件 @
28b07296
...
...
@@ -13,6 +13,7 @@ import com.android.build.api.transform.Status.REMOVED
import
com.android.build.api.transform.TransformInput
import
com.android.build.api.transform.TransformInvocation
import
com.android.build.api.transform.TransformOutputProvider
import
com.didichuxing.doraemonkit.plugin.transform.DoKitBaseTransform
import
com.didiglobal.booster.gradle.*
import
com.didiglobal.booster.kotlinx.NCPU
import
com.didiglobal.booster.transform.AbstractKlassPool
...
...
@@ -30,7 +31,7 @@ import java.util.concurrent.Future
*
* @author johnsonlee
*/
internal
class
DoKitTransformInvocation
(
private
val
delegate
:
TransformInvocation
,
internal
val
transform
:
DoKitTransform
)
:
TransformInvocation
,
TransformContext
,
ArtifactManager
{
internal
class
DoKitTransformInvocation
(
private
val
delegate
:
TransformInvocation
,
internal
val
transform
:
DoKit
Base
Transform
)
:
TransformInvocation
,
TransformContext
,
ArtifactManager
{
private
val
executor
=
Executors
.
newWorkStealingPool
(
NCPU
)
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmclasstransformer/BaseDoKitClassTransformer.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.asmclasstransformer
import
com.didiglobal.booster.transform.asm.ClassTransformer
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/21-16:54
* 描 述:
* 修订历史:
* ================================================
*/
open
class
BaseDoKitClassTransformer
:
ClassTransformer
{
}
\ No newline at end of file
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmclasstransformer/MethodStackDepTransformer.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.asmclasstransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import
com.didichuxing.doraemonkit.plugin.getMethodExitInsnNodes
import
com.didichuxing.doraemonkit.plugin.ownerClassName
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil
import
com.didiglobal.booster.transform.TransformContext
import
com.didiglobal.booster.transform.asm.asIterable
import
com.didiglobal.booster.transform.asm.className
import
org.objectweb.asm.Opcodes.*
import
org.objectweb.asm.tree.*
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/14-18:07
* 描 述:入口函数 慢函数调用栈 wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
* 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建
* 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的
* ================================================
*/
class
MethodStackDepTransformer
(
private
val
level
:
Int
=
1
)
:
BaseDoKitClassTransformer
()
{
private
val
thresholdTime
=
DoKitExtUtil
.
slowMethodExt
.
stackMethod
.
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_NORMAL
)
{
return
klass
}
if
(
DoKitExtUtil
.
ignorePackageNames
(
klass
.
className
))
{
return
klass
}
val
methodStackKeys
:
MutableSet
<
String
>
=
MethodStackNodeUtil
.
METHOD_STACK_KEYS
[
level
-
1
]
klass
.
methods
.
forEach
{
methodNode
->
val
key
=
"${klass.className}&${methodNode.name}&${methodNode.desc}"
if
(
methodStackKeys
.
contains
(
key
))
{
println
(
"level===>$level mathched key===>$key"
)
operateMethodInsn
(
klass
,
methodNode
)
}
}
return
klass
}
private
fun
operateMethodInsn
(
klass
:
ClassNode
,
methodNode
:
MethodNode
)
{
//读取全是函数调用的指令
methodNode
.
instructions
.
asIterable
().
filterIsInstance
(
MethodInsnNode
::
class
.
java
).
filter
{
methodInsnNode
->
methodInsnNode
.
name
!=
"<init>"
}.
forEach
{
methodInsnNode
->
val
methodStackNode
=
MethodStackNode
(
level
,
methodInsnNode
.
ownerClassName
,
methodInsnNode
.
name
,
methodInsnNode
.
desc
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
)
MethodStackNodeUtil
.
addMethodStackNode
(
level
,
methodStackNode
)
}
//函数出入口插入耗时统计代码
//方法入口插入
methodNode
.
instructions
.
insert
(
createMethodEnterInsnList
(
level
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
,
methodNode
.
access
))
//方法出口插入
methodNode
.
instructions
.
getMethodExitInsnNodes
()
?.
forEach
{
methodExitInsnNode
->
methodNode
.
instructions
.
insertBefore
(
methodExitInsnNode
,
createMethodExitInsnList
(
level
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
,
methodNode
.
access
))
}
}
/**
* 创建慢函数入口指令集
*/
private
fun
createMethodEnterInsnList
(
level
:
Int
,
className
:
String
,
methodName
:
String
,
desc
:
String
,
access
:
Int
):
InsnList
{
val
isStaticMethod
=
access
and
ACC_STATIC
!=
0
val
insnList
=
InsnList
()
if
(
isStaticMethod
)
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
DoKitExtUtil
.
mStackMethodLevel
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeStaticMethodCostStart"
,
"(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"
,
false
))
}
else
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
DoKitExtUtil
.
mStackMethodLevel
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
VarInsnNode
(
ALOAD
,
0
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeObjectMethodCostStart"
,
"(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"
,
false
))
}
return
insnList
}
/**
* 创建慢函数退出时的指令集
*/
private
fun
createMethodExitInsnList
(
level
:
Int
,
className
:
String
,
methodName
:
String
,
desc
:
String
,
access
:
Int
):
InsnList
{
val
isStaticMethod
=
access
and
ACC_STATIC
!=
0
val
insnList
=
InsnList
()
if
(
isStaticMethod
)
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeStaticMethodCostEnd"
,
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"
,
false
))
}
else
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
VarInsnNode
(
ALOAD
,
0
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeObjectMethodCostEnd"
,
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"
,
false
))
}
return
insnList
}
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/BaseDoKitAsmTransformer.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.asmtransformer
import
com.didichuxing.doraemonkit.plugin.asmclasstransformer.BaseDoKitClassTransformer
import
com.didiglobal.booster.annotations.Priority
import
com.didiglobal.booster.transform.TransformContext
import
com.didiglobal.booster.transform.Transformer
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassWriter
import
org.objectweb.asm.tree.ClassNode
import
java.lang.management.ManagementFactory
import
java.lang.management.ThreadMXBean
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/21-16:44
* 描 述:
* 修订历史:
* ================================================
*/
open
class
BaseDoKitAsmTransformer
:
Transformer
{
private
val
threadMxBean
=
ManagementFactory
.
getThreadMXBean
()
private
val
durations
=
mutableMapOf
<
BaseDoKitClassTransformer
,
Long
>()
internal
val
transformers
:
Collection
<
BaseDoKitClassTransformer
>
/**
* For unit test only
*/
constructor
(
vararg
transformers
:
BaseDoKitClassTransformer
)
{
this
.
transformers
=
transformers
.
sortedBy
{
it
.
javaClass
.
getAnnotation
(
Priority
::
class
.
java
)
?.
value
?:
0
}
}
override
fun
onPreTransform
(
context
:
TransformContext
)
{
this
.
transformers
.
forEach
{
transformer
->
this
.
threadMxBean
.
sumCpuTime
(
transformer
)
{
transformer
.
onPreTransform
(
context
)
}
}
}
override
fun
transform
(
context
:
TransformContext
,
bytecode
:
ByteArray
):
ByteArray
{
return
ClassWriter
(
ClassWriter
.
COMPUTE_MAXS
).
also
{
writer
->
this
.
transformers
.
fold
(
ClassNode
().
also
{
klass
->
ClassReader
(
bytecode
).
accept
(
klass
,
0
)
})
{
klass
,
transformer
->
this
.
threadMxBean
.
sumCpuTime
(
transformer
)
{
transformer
.
transform
(
context
,
klass
)
}
}.
accept
(
writer
)
}.
toByteArray
()
}
override
fun
onPostTransform
(
context
:
TransformContext
)
{
this
.
transformers
.
forEach
{
transformer
->
this
.
threadMxBean
.
sumCpuTime
(
transformer
)
{
transformer
.
onPostTransform
(
context
)
}
}
val
w1
=
this
.
durations
.
keys
.
map
{
it
.
javaClass
.
name
.
length
}.
max
()
?:
20
this
.
durations
.
forEach
{
(
transformer
,
ns
)
->
println
(
"${transformer.javaClass.name.padEnd(w1 + 1)}: ${ns / 1000000} ms"
)
}
}
private
fun
<
R
>
ThreadMXBean
.
sumCpuTime
(
transformer
:
BaseDoKitClassTransformer
,
action
:
()
->
R
):
R
{
val
ct0
=
this
.
currentThreadCpuTime
val
result
=
action
()
val
ct1
=
this
.
currentThreadCpuTime
durations
[
transformer
]
=
durations
.
getOrDefault
(
transformer
,
0
)
+
(
ct1
-
ct0
)
return
result
}
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/asmtransformer/DoKitAsmTransformer.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.asmtransformer
import
com.didichuxing.doraemonkit.plugin.asmclasstransformer.MethodStackDepTransformer
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/21-16:44
* 描 述:
* 修订历史:
* ================================================
*/
class
DoKitAsmTransformer
(
val
level
:
Int
)
:
BaseDoKitAsmTransformer
(
MethodStackDepTransformer
(
level
))
{
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
transform
/BigImgTransformer.kt
→
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
classtransformer
/BigImgTransformer.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
package
com.didichuxing.doraemonkit.plugin.
classtransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.
methodExitInsnNode
import
com.didichuxing.doraemonkit.plugin.
getMethodExitInsnNodes
import
com.didiglobal.booster.annotations.Priority
import
com.didiglobal.booster.transform.TransformContext
import
com.didiglobal.booster.transform.asm.ClassTransformer
...
...
@@ -25,10 +25,12 @@ import org.objectweb.asm.tree.VarInsnNode
@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(klass.className == "com.didichuxing.doraemondemo.App"){
// println("===BigImgTransformer====transform===")
// }
if
(!
DoKitExtUtil
.
dokitPluginSwitchOpen
())
{
return
klass
}
...
...
@@ -49,8 +51,8 @@ class BigImgTransformer : ClassTransformer {
(
methodNode
.
name
==
"init"
||
methodNode
.
name
==
"<init>"
)
&&
methodNode
.
desc
!=
null
}.
let
{
methodNode
->
//函数结束的地方插入
methodNode
?.
instructions
?.
methodExitInsnNode
().
let
{
methodNode
?
.
instructions
?.
insertBefore
(
it
,
createGlideInsnList
())
methodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
methodNode
.
instructions
?.
insertBefore
(
it
,
createGlideInsnList
())
}
}
}
...
...
@@ -61,8 +63,8 @@ class BigImgTransformer : ClassTransformer {
methodNode
.
name
==
"<init>"
&&
methodNode
.
desc
!=
null
}.
let
{
methodNode
->
//函数结束的地方插入
methodNode
?.
instructions
?.
methodExitInsnNode
().
let
{
methodNode
?
.
instructions
?.
insertBefore
(
it
,
createPicassoInsnList
())
methodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
methodNode
.
instructions
?.
insertBefore
(
it
,
createPicassoInsnList
())
}
}
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
transform
/CommTransformer.kt
→
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
classtransformer
/CommTransformer.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
package
com.didichuxing.doraemonkit.plugin.
classtransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import
com.didichuxing.doraemonkit.plugin.
methodExitInsnNode
import
com.didichuxing.doraemonkit.plugin.
getMethodExitInsnNodes
import
com.didiglobal.booster.annotations.Priority
import
com.didiglobal.booster.transform.TransformContext
import
com.didiglobal.booster.transform.asm.ClassTransformer
...
...
@@ -29,6 +29,9 @@ class CommTransformer : ClassTransformer {
}
override
fun
transform
(
context
:
TransformContext
,
klass
:
ClassNode
):
ClassNode
{
// if(klass.className == "com.didichuxing.doraemondemo.App"){
// println("===CommTransformer====transform===")
// }
if
(!
DoKitExtUtil
.
dokitPluginSwitchOpen
())
{
return
klass
}
...
...
@@ -78,15 +81,17 @@ class CommTransformer : ClassTransformer {
val
zeroConsMethodNode
=
klass
.
methods
?.
find
{
it
.
name
==
"<init>"
&&
it
.
desc
==
"()V"
}
val
zeroReturnInsnNode
=
zeroConsMethodNode
?.
instructions
?.
methodExitInsnNode
()
zeroConsMethodNode
?.
instructions
?.
insertBefore
(
zeroReturnInsnNode
,
createOkHttpZeroConsInsnList
())
zeroConsMethodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
zeroConsMethodNode
.
instructions
.
insertBefore
(
it
,
createOkHttpZeroConsInsnList
())
}
//一个参数的构造方法
val
oneConsMethodNode
=
klass
.
methods
?.
find
{
it
.
name
==
"<init>"
&&
it
.
desc
==
"(Lokhttp3/OkHttpClient;)V"
}
val
oneReturnInsnNode
=
oneConsMethodNode
?.
instructions
?.
methodExitInsnNode
()
oneConsMethodNode
?.
instructions
?.
insertBefore
(
oneReturnInsnNode
,
createOkHttpOneConsInsnList
())
oneConsMethodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
oneConsMethodNode
.
instructions
.
insertBefore
(
it
,
createOkHttpOneConsInsnList
())
}
}
//didi platform
...
...
@@ -95,16 +100,18 @@ class CommTransformer : ClassTransformer {
val
zeroConsMethodNode
=
klass
.
methods
?.
find
{
it
.
name
==
"<init>"
&&
it
.
desc
==
"()V"
}
val
zeroReturnInsnNode
=
zeroConsMethodNode
?.
instructions
?.
methodExitInsnNode
()
zeroConsMethodNode
?.
instructions
?.
insertBefore
(
zeroReturnInsnNode
,
createDidiHttpZeroConsInsnList
())
zeroConsMethodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
zeroConsMethodNode
.
instructions
.
insertBefore
(
it
,
createDidiHttpZeroConsInsnList
())
}
//一个参数的构造方法
val
oneConsMethodNode
=
klass
.
methods
?.
find
{
it
.
name
==
"<init>"
&&
it
.
desc
==
"(Ldidihttp/DidiHttpClient;)V"
}
val
oneReturnInsnNode
=
oneConsMethodNode
?.
instructions
?.
methodExitInsnNode
()
oneConsMethodNode
?.
instructions
?.
insertBefore
(
oneReturnInsnNode
,
createDidiHttpOneConsInsnList
())
oneConsMethodNode
?.
instructions
?.
getMethodExitInsnNodes
()
?.
forEach
{
oneConsMethodNode
.
instructions
.
insertBefore
(
it
,
createDidiHttpOneConsInsnList
())
}
}
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/classtransformer/EnterMethodStackTransformer.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.classtransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import
com.didichuxing.doraemonkit.plugin.getMethodExitInsnNodes
import
com.didichuxing.doraemonkit.plugin.ownerClassName
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNode
import
com.didichuxing.doraemonkit.plugin.stack_method.MethodStackNodeUtil
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
* 修订历史:不要指定自动注入 需要手动在DoKitAsmTransformer中通过配置创建
* 原理:transform()方法的调用是无序的 原因:哪一个class会先被transformer执行是不确定的 但是每一个class被transformer执行顺序是遵循transformer的Priority规则的
* ================================================
*/
@Priority
(
4
)
@AutoService
(
ClassTransformer
::
class
)
class
EnterMethodStackTransformer
:
ClassTransformer
{
private
val
thresholdTime
=
DoKitExtUtil
.
slowMethodExt
.
stackMethod
.
thresholdTime
private
val
level
=
0
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_NORMAL
)
{
return
klass
}
if
(
DoKitExtUtil
.
ignorePackageNames
(
klass
.
className
))
{
return
klass
}
//默认为Application onCreate 和attachBaseContext
val
enterMethods
=
DoKitExtUtil
.
slowMethodExt
.
stackMethod
.
enterMethods
//找不到配置的Application
if
(
enterMethods
.
isEmpty
())
{
val
superName
=
klass
.
superName
//先判断父类
if
(
superName
.
isNotEmpty
()
&&
(
superName
==
"android/app/Application"
||
superName
==
"android/support/multidex/MultiDexApplication"
||
superName
==
"androidx/multidex/MultiDexApplication"
))
{
klass
.
methods
.
filter
{
methodNode
->
(
methodNode
.
name
==
"onCreate"
&&
methodNode
.
desc
==
"()V"
)
||
(
methodNode
.
name
==
"attachBaseContext"
&&
methodNode
.
desc
==
"(Landroid/content/Context;)V"
)
}.
let
{
methodNodes
->
//读取全是函数调用的Insn
methodNodes
.
forEach
{
methodNode
->
operateMethodInsn
(
klass
,
methodNode
)
}
}
}
}
else
{
enterMethods
.
forEach
{
enterMethodName
->
klass
.
methods
.
forEach
{
methodNode
->
val
allMethodName
=
"${klass.className}.${methodNode.name}"
if
(
allMethodName
==
enterMethodName
)
{
println
(
"level===>$level mathched enterMethod===>$allMethodName"
)
operateMethodInsn
(
klass
,
methodNode
)
}
}
}
}
return
klass
}
private
fun
operateMethodInsn
(
klass
:
ClassNode
,
methodNode
:
MethodNode
)
{
//读取全是函数调用的指令
methodNode
.
instructions
.
asIterable
().
filterIsInstance
(
MethodInsnNode
::
class
.
java
).
filter
{
methodInsnNode
->
methodInsnNode
.
name
!=
"<init>"
}.
forEach
{
methodInsnNode
->
val
methodStackNode
=
MethodStackNode
(
level
,
methodInsnNode
.
ownerClassName
,
methodInsnNode
.
name
,
methodInsnNode
.
desc
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
)
MethodStackNodeUtil
.
addMethodStackNode
(
level
,
methodStackNode
)
}
//函数出入口插入耗时统计代码
//方法入口插入
methodNode
.
instructions
.
insert
(
createMethodEnterInsnList
(
level
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
,
methodNode
.
access
))
//方法出口插入
methodNode
.
instructions
.
getMethodExitInsnNodes
()
?.
forEach
{
methodExitInsnNode
->
methodNode
.
instructions
.
insertBefore
(
methodExitInsnNode
,
createMethodExitInsnList
(
level
,
klass
.
className
,
methodNode
.
name
,
methodNode
.
desc
,
methodNode
.
access
))
}
}
/**
* 创建慢函数入口指令集
*/
private
fun
createMethodEnterInsnList
(
level
:
Int
,
className
:
String
,
methodName
:
String
,
desc
:
String
,
access
:
Int
):
InsnList
{
val
isStaticMethod
=
access
and
ACC_STATIC
!=
0
val
insnList
=
InsnList
()
if
(
isStaticMethod
)
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
DoKitExtUtil
.
mStackMethodLevel
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeStaticMethodCostStart"
,
"(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"
,
false
))
}
else
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
DoKitExtUtil
.
mStackMethodLevel
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
VarInsnNode
(
ALOAD
,
0
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeObjectMethodCostStart"
,
"(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"
,
false
))
}
return
insnList
}
/**
* 创建慢函数退出时的指令集
*/
private
fun
createMethodExitInsnList
(
level
:
Int
,
className
:
String
,
methodName
:
String
,
desc
:
String
,
access
:
Int
):
InsnList
{
val
isStaticMethod
=
access
and
ACC_STATIC
!=
0
val
insnList
=
InsnList
()
if
(
isStaticMethod
)
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeStaticMethodCostEnd"
,
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"
,
false
))
}
else
{
insnList
.
add
(
MethodInsnNode
(
INVOKESTATIC
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"getInstance"
,
"()Lcom/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil;"
,
false
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
thresholdTime
))
insnList
.
add
(
IntInsnNode
(
BIPUSH
,
level
))
insnList
.
add
(
LdcInsnNode
(
className
))
insnList
.
add
(
LdcInsnNode
(
methodName
))
insnList
.
add
(
LdcInsnNode
(
desc
))
insnList
.
add
(
VarInsnNode
(
ALOAD
,
0
))
insnList
.
add
(
MethodInsnNode
(
INVOKEVIRTUAL
,
"com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil"
,
"recodeObjectMethodCostEnd"
,
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"
,
false
))
}
return
insnList
}
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
transform
/GlobalSlowMethodTransformer.kt
→
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
classtransformer
/GlobalSlowMethodTransformer.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
package
com.didichuxing.doraemonkit.plugin.
classtransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.extension.SlowMethodExt
import
com.didichuxing.doraemonkit.plugin.
methodExitInsnNode
import
com.didichuxing.doraemonkit.plugin.
getMethodExitInsnNodes
import
com.didiglobal.booster.annotations.Priority
import
com.didiglobal.booster.transform.TransformContext
import
com.didiglobal.booster.transform.asm.ClassTransformer
...
...
@@ -17,7 +17,7 @@ import org.objectweb.asm.tree.*
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/14-18:07
* 描 述:全局业务代码
慢函数
wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
* 描 述:全局业务代码
慢函数
wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
* 修订历史:
* ================================================
*/
...
...
@@ -25,7 +25,11 @@ import org.objectweb.asm.tree.*
@AutoService
(
ClassTransformer
::
class
)
class
GlobalSlowMethodTransformer
:
ClassTransformer
{
val
thresholdTime
=
DoKitExtUtil
.
slowMethodExt
.
normalMethod
.
thresholdTime
override
fun
transform
(
context
:
TransformContext
,
klass
:
ClassNode
):
ClassNode
{
// if(klass.className == "com.didichuxing.doraemondemo.App"){
// println("===GlobalSlowMethodTransformer====transform===")
// }
if
(!
DoKitExtUtil
.
dokitPluginSwitchOpen
())
{
return
klass
}
...
...
@@ -56,7 +60,7 @@ class GlobalSlowMethodTransformer : ClassTransformer {
//方法入口插入
methodNode
.
instructions
.
insert
(
createMethodEnterInsnList
(
className
,
methodNode
.
name
,
methodNode
.
access
))
//方法出口插入
methodNode
.
instructions
.
methodExitInsnNode
().
let
{
methodExitInsnNode
->
methodNode
.
instructions
.
getMethodExitInsnNodes
()
?.
forEach
{
methodExitInsnNode
->
methodNode
.
instructions
.
insertBefore
(
methodExitInsnNode
,
createMethodExitInsnList
(
className
,
methodNode
.
name
,
methodNode
.
access
))
}
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
transform
/UrlConnectionTransformer.kt
→
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
classtransformer
/UrlConnectionTransformer.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
package
com.didichuxing.doraemonkit.plugin.
classtransformer
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didiglobal.booster.annotations.Priority
...
...
@@ -28,6 +28,9 @@ class UrlConnectionTransformer : ClassTransformer {
private
val
DESC
=
"(Ljava/net/URLConnection;)Ljava/net/URLConnection;"
override
fun
transform
(
context
:
TransformContext
,
klass
:
ClassNode
):
ClassNode
{
// if(klass.className == "com.didichuxing.doraemondemo.App"){
// println("===UrlConnectionTransformer====transform===")
// }
if
(!
DoKitExtUtil
.
dokitPluginSwitchOpen
())
{
return
klass
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/DoKitExt.kt
浏览文件 @
28b07296
...
...
@@ -7,7 +7,6 @@ import org.gradle.api.Action
*/
open
class
DoKitExt
(
var
dokitPluginSwitch
:
Boolean
=
true
,
var
dokitLogSwitch
:
Boolean
=
true
,
var
usefulInRelease
:
Boolean
=
false
,
var
comm
:
CommExt
=
CommExt
(),
var
slowMethod
:
SlowMethodExt
=
SlowMethodExt
())
{
...
...
@@ -21,9 +20,6 @@ open class DoKitExt(var dokitPluginSwitch: Boolean = true,
this
.
dokitLogSwitch
=
dokitLogSwitch
}
fun
usefulInRelease
(
usefulInRelease
:
Boolean
)
{
this
.
usefulInRelease
=
usefulInRelease
}
/**
* 让comm 支持 DSL 语法
...
...
@@ -44,7 +40,7 @@ open class DoKitExt(var dokitPluginSwitch: Boolean = true,
}
override
fun
toString
():
String
{
return
"DoKitExt(dokitPluginSwitch=$dokitPluginSwitch, dokitLogSwitch=$dokitLogSwitch,
usefulInRelease=$usefulInRelease,
comm=$comm, slowMethod=$slowMethod)"
return
"DoKitExt(dokitPluginSwitch=$dokitPluginSwitch, dokitLogSwitch=$dokitLogSwitch, comm=$comm, slowMethod=$slowMethod)"
}
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/extension/SlowMethodExt.kt
浏览文件 @
28b07296
...
...
@@ -56,16 +56,16 @@ open class SlowMethodExt(
this
.
thresholdTime
=
thresholdTime
}
fun
normalMethod
(
enterMethods
:
MutableSet
<
String
>)
{
this
.
enterMethods
=
enterMethods
}
override
fun
toString
():
String
{
return
"StackMethodExt{"
+
"thresholdTime="
+
thresholdTime
+
", enterMethods="
+
enterMethods
+
'}'
return
"StackMethodExt(thresholdTime=$thresholdTime, enterMethods=$enterMethods)"
}
}
class
NormalMethodExt
(
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/processor/DoKitPluginConfigProcessor.kt
浏览文件 @
28b07296
...
...
@@ -5,6 +5,7 @@ import com.android.build.gradle.api.BaseVariant
import
com.android.build.gradle.api.LibraryVariant
import
com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import
com.didichuxing.doraemonkit.plugin.extension.DoKitExt
import
com.didichuxing.doraemonkit.plugin.transform.*
import
com.didiglobal.booster.gradle.getAndroid
import
com.didiglobal.booster.gradle.isDynamicFeature
import
com.didiglobal.booster.gradle.project
...
...
@@ -14,6 +15,7 @@ import com.didiglobal.booster.transform.ArtifactManager
import
com.didiglobal.booster.transform.artifacts
import
com.didiglobal.booster.transform.util.ComponentHandler
import
com.google.auto.service.AutoService
import
org.gradle.api.Project
import
javax.xml.parsers.SAXParserFactory
/**
...
...
@@ -37,7 +39,6 @@ class DoKitPluginConfigProcessor : VariantProcessor {
val
parser
=
SAXParserFactory
.
newInstance
().
newSAXParser
()
val
handler
=
ComponentHandler
()
parser
.
parse
(
manifest
,
handler
)
//println("handler====>${handler.applications}")
DoKitExtUtil
.
setApplications
(
handler
.
applications
)
}
...
...
@@ -47,10 +48,9 @@ class DoKitPluginConfigProcessor : VariantProcessor {
//查找Application路径
val
doKitExt
=
variant
.
project
.
extensions
.
getByType
(
DoKitExt
::
class
.
java
)
DoKitExtUtil
.
init
(
doKitExt
,
appExt
.
defaultConfig
.
applicationId
)
// println("doKitExt====>$doKitExt applicationId===>${appExt.defaultConfig.applicationId}")
}
//println("variant====>${variant.name}")
}
}
\ No newline at end of file
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNode.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.stack_method
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/20-16:50
* 描 述:
* 修订历史:
* ================================================
*/
data class
MethodStackNode
(
var
level
:
Int
,
var
className
:
String
,
var
methodName
:
String
,
var
desc
:
String
,
var
parentClassName
:
String
,
var
parentMethodName
:
String
,
var
parentDesc
:
String
)
\ No newline at end of file
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/stack_method/MethodStackNodeUtil.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.stack_method
import
org.gradle.internal.impldep.org.apache.commons.lang.mutable.Mutable
import
java.util.*
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/5/20-16:58
* 描 述:
* 修订历史:
* ================================================
*/
object
MethodStackNodeUtil
{
val
METHOD_STACK_KEYS
:
MutableList
<
MutableSet
<
String
>>
by
lazy
{
Collections
.
synchronizedList
(
mutableListOf
<
MutableSet
<
String
>>())
}
fun
addMethodStackNode
(
level
:
Int
,
methodStackNode
:
MethodStackNode
)
{
val
key
=
"${methodStackNode.className}&${methodStackNode.methodName}&${methodStackNode.desc}"
METHOD_STACK_KEYS
[
level
].
add
(
key
)
}
}
\ No newline at end of file
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
DoKit
Transform.kt
→
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/
transform/DoKitBase
Transform.kt
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin
package
com.didichuxing.doraemonkit.plugin
.transform
import
com.android.build.api.transform.QualifiedContent
import
com.android.build.api.transform.Transform
...
...
@@ -6,6 +6,7 @@ import com.android.build.api.transform.TransformInvocation
import
com.android.build.gradle.BaseExtension
import
com.android.build.gradle.internal.pipeline.TransformManager
import
com.android.build.gradle.internal.pipeline.TransformManager.SCOPE_FULL_PROJECT
import
com.didichuxing.doraemonkit.plugin.DoKitTransformInvocation
import
com.didiglobal.booster.gradle.SCOPE_FULL_WITH_FEATURES
import
com.didiglobal.booster.gradle.SCOPE_PROJECT
import
com.didiglobal.booster.gradle.getAndroid
...
...
@@ -16,15 +17,15 @@ import java.util.ServiceLoader
/**
* Represents the transform base
*
*
DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer
* @author johnsonlee
*/
open
class
DoKitTransform
(
val
project
:
Project
)
:
Transform
()
{
open
class
DoKit
Base
Transform
(
val
project
:
Project
)
:
Transform
()
{
/*
* Preload transformers as List to fix NoSuchElementException caused by ServiceLoader in parallel mode
*/
internal
val
transformers
=
ServiceLoader
.
load
(
Transformer
::
class
.
java
,
javaClass
.
classLoader
).
toList
()
internal
open
val
transformers
=
ServiceLoader
.
load
(
Transformer
::
class
.
java
,
javaClass
.
classLoader
).
toList
()
private
val
androidExt
:
BaseExtension
=
project
.
getAndroid
()
...
...
@@ -39,7 +40,7 @@ open class DoKitTransform(val project: Project) : Transform() {
val
bootKlassPool
:
AbstractKlassPool
get
()
=
androidKlassPool
override
fun
getName
()
=
"booster"
override
fun
getName
()
=
this
.
javaClass
.
simpleName
override
fun
isIncremental
()
=
true
...
...
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitCommTransform.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.transform
import
org.gradle.api.Project
/**
* Represents the transform base
* DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer、EnterMethodStackTransformer
* @author johnsonlee
*/
class
DoKitCommTransform
(
androidProject
:
Project
)
:
DoKitBaseTransform
(
androidProject
)
{
}
Android/buildSrc/src/main/kotlin/com/didichuxing/doraemonkit/plugin/transform/DoKitDependTransform.kt
0 → 100644
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.transform
import
com.didichuxing.doraemonkit.plugin.asmtransformer.DoKitAsmTransformer
import
com.didiglobal.booster.transform.Transformer
import
org.gradle.api.Project
/**
* Represents the transform base
* DoKitCommTransform 作用于 CommTransformer、BigImgTransformer、UrlConnectionTransformer、GlobalSlowMethodTransformer
* @author johnsonlee
*/
open
class
DoKitDependTransform
(
androidProject
:
Project
,
val
level
:
Int
)
:
DoKitBaseTransform
(
androidProject
)
{
internal
override
val
transformers
=
mutableListOf
<
Transformer
>(
DoKitAsmTransformer
(
level
))
override
fun
getName
():
String
{
return
"${this.javaClass.simpleName}_$level"
}
}
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/DoKitPlugin.java
浏览文件 @
28b07296
...
...
@@ -2,15 +2,15 @@ package com.didichuxing.doraemonkit.plugin;
import
com.android.build.gradle.AppExtension
;
import
com.didichuxing.doraemonkit.plugin.extension.DoKitExt
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitBigImageTransform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitCommTransform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitMethodStack0Transform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitMethodStack1Transform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitMethodStack2Transform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitMethodStack3Transform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitMethodStack4Transform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitSlowMethodTransform
;
import
com.didichuxing.doraemonkit.plugin.
transform
.DokitUrlConnectionTransform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitBigImageTransform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitCommTransform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitMethodStack0Transform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitMethodStack1Transform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitMethodStack2Transform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitMethodStack3Transform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitMethodStack4Transform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitSlowMethodTransform
;
import
com.didichuxing.doraemonkit.plugin.
classtransformer
.DokitUrlConnectionTransform
;
import
com.didiglobal.booster.gradle.BaseVariantKt
;
import
com.didiglobal.booster.gradle.VariantScopeKt
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitBigImageTransform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitCommTransform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack0Transform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack1Transform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack2Transform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack3Transform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitMethodStack4Transform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitSlowMethodTransform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit-plugin/src/main/groovy/com/didichuxing/doraemonkit/plugin/transform/DokitUrlConnectionTransform.java
浏览文件 @
28b07296
package
com.didichuxing.doraemonkit.plugin.
transform
;
package
com.didichuxing.doraemonkit.plugin.
classtransformer
;
import
com.android.build.api.transform.Context
;
import
com.android.build.api.transform.TransformException
;
...
...
Android/doraemonkit/build.gradle
浏览文件 @
28b07296
...
...
@@ -67,7 +67,7 @@ dependencies {
implementation
rootProject
.
ext
.
dependencies
[
"okhttp"
]
implementation
rootProject
.
ext
.
dependencies
[
"okhttp_v2"
]
implementation
rootProject
.
ext
.
dependencies
[
"room_runtime"
]
annotationProcessor
rootProject
.
ext
.
dependencies
[
"room_compile"
]
kapt
rootProject
.
ext
.
dependencies
[
"room_compile"
]
//三大图片框架
compileOnly
rootProject
.
ext
.
dependencies
[
"glide"
]
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/DoraemonKitReal.kt
浏览文件 @
28b07296
...
...
@@ -176,7 +176,7 @@ object DoraemonKitReal {
* 添加内置kit
*/
private
fun
addInnerKit
(
application
:
Application
)
{
va
r
json
=
""
va
l
json
:
String
?
if
(
FileUtils
.
isFileExists
(
DokitConstant
.
SYSTEM_KITS_BAK_PATH
))
{
json
=
FileIOUtils
.
readFile2String
(
DokitConstant
.
SYSTEM_KITS_BAK_PATH
)
}
else
{
...
...
@@ -353,7 +353,7 @@ object DoraemonKitReal {
return
}
val
files
=
rootFileDir
.
listFiles
()
f
or
(
file
in
files
)
{
f
iles
?.
forEach
{
file
->
if
(
file
.
isDirectory
)
{
//若是目录,则递归打印该目录下的文件
//LogHelper.i(TAG, "文件夹==>" + file.getAbsolutePath());
...
...
@@ -372,6 +372,7 @@ object DoraemonKitReal {
//LogHelper.i(TAG, "文件==>" + file.getAbsolutePath() + " fileName===>" + FileUtils.getFileName(file) + " fileLength===>" + fileLength);
}
}
}
/**
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/aop/method_stack/MethodStackUtil.java
浏览文件 @
28b07296
...
...
@@ -9,6 +9,8 @@ import com.didichuxing.doraemonkit.aop.MethodCostUtil;
import
com.didichuxing.doraemonkit.kit.timecounter.TimeCounterManager
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.concurrent.ConcurrentHashMap
;
...
...
@@ -26,12 +28,13 @@ public class MethodStackUtil {
/**
* key className&methodName
*/
private
ConcurrentHashMap
<
String
,
MethodInvokNode
>
ROOT_METHOD_STACKS
=
new
ConcurrentHashMap
<>();
private
ConcurrentHashMap
<
String
,
MethodInvokNode
>
LEVEL1_METHOD_STACKS
=
new
ConcurrentHashMap
<>();
private
ConcurrentHashMap
<
String
,
MethodInvokNode
>
LEVEL2_METHOD_STACKS
=
new
ConcurrentHashMap
<>();
private
ConcurrentHashMap
<
String
,
MethodInvokNode
>
LEVEL3_METHOD_STACKS
=
new
ConcurrentHashMap
<>();
private
ConcurrentHashMap
<
String
,
MethodInvokNode
>
LEVEL4_METHOD_STACKS
=
new
ConcurrentHashMap
<>();
//
private ConcurrentHashMap<String, MethodInvokNode> ROOT_METHOD_STACKS = new ConcurrentHashMap<>();
//
private ConcurrentHashMap<String, MethodInvokNode> LEVEL1_METHOD_STACKS = new ConcurrentHashMap<>();
//
private ConcurrentHashMap<String, MethodInvokNode> LEVEL2_METHOD_STACKS = new ConcurrentHashMap<>();
//
private ConcurrentHashMap<String, MethodInvokNode> LEVEL3_METHOD_STACKS = new ConcurrentHashMap<>();
//
private ConcurrentHashMap<String, MethodInvokNode> LEVEL4_METHOD_STACKS = new ConcurrentHashMap<>();
private
List
<
ConcurrentHashMap
<
String
,
MethodInvokNode
>>
METHOD_STACKS
=
Collections
.
synchronizedList
(
new
ArrayList
<
ConcurrentHashMap
<
String
,
MethodInvokNode
>>());
/**
* 静态内部类单例
...
...
@@ -44,39 +47,37 @@ public class MethodStackUtil {
return
MethodStackUtil
.
Holder
.
INSTANCE
;
}
private
void
createMethodStackList
(
int
totalLevel
)
{
if
(
METHOD_STACKS
.
size
()
==
totalLevel
)
{
return
;
}
METHOD_STACKS
.
clear
();
for
(
int
index
=
0
;
index
<
totalLevel
;
index
++)
{
METHOD_STACKS
.
add
(
index
,
new
ConcurrentHashMap
<
String
,
MethodInvokNode
>());
}
}
/**
* @param
l
evel
* @param
currentL
evel
* @param methodName
* @param classObj null 代表静态函数
*/
public
void
recodeObjectMethodCostStart
(
int
thresholdTime
,
int
level
,
String
className
,
String
methodName
,
String
desc
,
Object
classObj
)
{
public
void
recodeObjectMethodCostStart
(
int
totalLevel
,
int
thresholdTime
,
int
currentLevel
,
String
className
,
String
methodName
,
String
desc
,
Object
classObj
)
{
try
{
//先创建队列
createMethodStackList
(
totalLevel
);
MethodInvokNode
methodInvokNode
=
new
MethodInvokNode
();
methodInvokNode
.
setStartTimeMillis
(
System
.
currentTimeMillis
());
methodInvokNode
.
setCurrentThreadName
(
Thread
.
currentThread
().
getName
());
methodInvokNode
.
setClassName
(
className
);
methodInvokNode
.
setMethodName
(
methodName
);
if
(
level
==
0
)
{
methodInvokNode
.
setLevel
(
0
);
ROOT_METHOD_STACKS
.
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
}
else
if
(
level
==
1
)
{
methodInvokNode
.
setLevel
(
1
);
LEVEL1_METHOD_STACKS
.
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
}
else
if
(
level
==
2
)
{
methodInvokNode
.
setLevel
(
2
);
LEVEL2_METHOD_STACKS
.
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
}
else
if
(
level
==
3
)
{
methodInvokNode
.
setLevel
(
3
);
LEVEL3_METHOD_STACKS
.
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
}
else
if
(
level
==
4
)
{
methodInvokNode
.
setLevel
(
4
);
LEVEL4_METHOD_STACKS
.
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
}
methodInvokNode
.
setLevel
(
currentLevel
);
METHOD_STACKS
.
get
(
currentLevel
).
put
(
String
.
format
(
"%s&%s"
,
className
,
methodName
),
methodInvokNode
);
//特殊判定
if
(
l
evel
==
0
)
{
if
(
currentL
evel
==
0
)
{
if
(
classObj
instanceof
Application
)
{
if
(
methodName
.
equals
(
"onCreate"
))
{
TimeCounterManager
.
get
().
onAppCreateStart
();
...
...
@@ -95,36 +96,25 @@ public class MethodStackUtil {
}
/**
* @param
l
evel
* @param
currentL
evel
* @param className
* @param methodName
* @param desc
* @param classObj null 代表静态函数
*/
public
void
recodeObjectMethodCostEnd
(
int
thresholdTime
,
int
l
evel
,
String
className
,
String
methodName
,
String
desc
,
Object
classObj
)
{
public
void
recodeObjectMethodCostEnd
(
int
thresholdTime
,
int
currentL
evel
,
String
className
,
String
methodName
,
String
desc
,
Object
classObj
)
{
synchronized
(
MethodCostUtil
.
class
)
{
try
{
MethodInvokNode
methodInvokNode
=
null
;
if
(
level
==
0
)
{
methodInvokNode
=
ROOT_METHOD_STACKS
.
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
}
else
if
(
level
==
1
)
{
methodInvokNode
=
LEVEL1_METHOD_STACKS
.
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
}
else
if
(
level
==
2
)
{
methodInvokNode
=
LEVEL2_METHOD_STACKS
.
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
}
else
if
(
level
==
3
)
{
methodInvokNode
=
LEVEL3_METHOD_STACKS
.
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
}
else
if
(
level
==
4
)
{
methodInvokNode
=
LEVEL4_METHOD_STACKS
.
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
}
MethodInvokNode
methodInvokNode
=
METHOD_STACKS
.
get
(
currentLevel
).
get
(
String
.
format
(
"%s&%s"
,
className
,
methodName
));
if
(
methodInvokNode
!=
null
)
{
methodInvokNode
.
setEndTimeMillis
(
System
.
currentTimeMillis
());
bindNode
(
thresholdTime
,
l
evel
,
methodInvokNode
);
bindNode
(
thresholdTime
,
currentL
evel
,
methodInvokNode
);
}
//打印函数调用栈
if
(
l
evel
==
0
)
{
if
(
currentL
evel
==
0
)
{
if
(
methodInvokNode
!=
null
)
{
toStack
(
classObj
instanceof
Application
,
methodInvokNode
);
}
...
...
@@ -139,7 +129,7 @@ public class MethodStackUtil {
}
//移除对象
ROOT_METHOD_STACKS
.
remove
(
className
+
"&"
+
methodName
);
METHOD_STACKS
.
get
(
0
)
.
remove
(
className
+
"&"
+
methodName
);
}
}
catch
(
Exception
e
)
{
...
...
@@ -155,18 +145,18 @@ public class MethodStackUtil {
int
index
=
0
;
for
(
int
i
=
0
;
i
<
stackTraceElements
.
length
;
i
++)
{
StackTraceElement
stackTraceElement
=
stackTraceElements
[
i
];
if
(
currentClassName
.
equals
(
stackTraceElement
.
getClassName
()
.
replaceAll
(
"\\."
,
"/"
)
)
&&
currentMethodName
.
equals
(
stackTraceElement
.
getMethodName
()))
{
if
(
currentClassName
.
equals
(
stackTraceElement
.
getClassName
())
&&
currentMethodName
.
equals
(
stackTraceElement
.
getMethodName
()))
{
index
=
i
;
break
;
}
}
StackTraceElement
parentStackTraceElement
=
stackTraceElements
[
index
+
1
];
return
String
.
format
(
"%s&%s"
,
parentStackTraceElement
.
getClassName
()
.
replaceAll
(
"\\."
,
"/"
)
,
parentStackTraceElement
.
getMethodName
());
return
String
.
format
(
"%s&%s"
,
parentStackTraceElement
.
getClassName
(),
parentStackTraceElement
.
getMethodName
());
}
private
void
bindNode
(
int
thresholdTime
,
int
l
evel
,
MethodInvokNode
methodInvokNode
)
{
private
void
bindNode
(
int
thresholdTime
,
int
currentL
evel
,
MethodInvokNode
methodInvokNode
)
{
if
(
methodInvokNode
==
null
)
{
return
;
}
...
...
@@ -176,55 +166,24 @@ public class MethodStackUtil {
return
;
}
MethodInvokNode
parentMethodNode
;
switch
(
level
)
{
case
1
:
//设置父node 并将自己添加到父node中
parentMethodNode
=
ROOT_METHOD_STACKS
.
get
(
getParentMethod
(
methodInvokNode
.
getClassName
(),
methodInvokNode
.
getMethodName
()));
if
(
parentMethodNode
!=
null
)
{
methodInvokNode
.
setParent
(
parentMethodNode
);
parentMethodNode
.
addChild
(
methodInvokNode
);
}
break
;
case
2
:
//设置父node 并将自己添加到父node中
parentMethodNode
=
LEVEL1_METHOD_STACKS
.
get
(
getParentMethod
(
methodInvokNode
.
getClassName
(),
methodInvokNode
.
getMethodName
()));
if
(
parentMethodNode
!=
null
)
{
methodInvokNode
.
setParent
(
parentMethodNode
);
parentMethodNode
.
addChild
(
methodInvokNode
);
}
break
;
case
3
:
//设置父node 并将自己添加到父node中
parentMethodNode
=
LEVEL2_METHOD_STACKS
.
get
(
getParentMethod
(
methodInvokNode
.
getClassName
(),
methodInvokNode
.
getMethodName
()));
if
(
parentMethodNode
!=
null
)
{
methodInvokNode
.
setParent
(
parentMethodNode
);
parentMethodNode
.
addChild
(
methodInvokNode
);
}
break
;
case
4
:
//设置父node 并将自己添加到父node中
parentMethodNode
=
LEVEL3_METHOD_STACKS
.
get
(
getParentMethod
(
methodInvokNode
.
getClassName
(),
methodInvokNode
.
getMethodName
()));
if
(
parentMethodNode
!=
null
)
{
methodInvokNode
.
setParent
(
parentMethodNode
);
parentMethodNode
.
addChild
(
methodInvokNode
);
}
break
;
default
:
break
;
if
(
currentLevel
>=
1
)
{
MethodInvokNode
parentMethodNode
=
METHOD_STACKS
.
get
(
currentLevel
-
1
).
get
(
getParentMethod
(
methodInvokNode
.
getClassName
(),
methodInvokNode
.
getMethodName
()));
if
(
parentMethodNode
!=
null
)
{
methodInvokNode
.
setParent
(
parentMethodNode
);
parentMethodNode
.
addChild
(
methodInvokNode
);
}
}
}
public
void
recodeStaticMethodCostStart
(
int
t
hresholdTime
,
int
l
evel
,
String
className
,
String
methodName
,
String
desc
)
{
recodeObjectMethodCostStart
(
t
hresholdTime
,
l
evel
,
className
,
methodName
,
desc
,
new
StaicMethodObject
());
public
void
recodeStaticMethodCostStart
(
int
t
otalLevel
,
int
thresholdTime
,
int
currentL
evel
,
String
className
,
String
methodName
,
String
desc
)
{
recodeObjectMethodCostStart
(
t
otalLevel
,
thresholdTime
,
currentL
evel
,
className
,
methodName
,
desc
,
new
StaicMethodObject
());
}
public
void
recodeStaticMethodCostEnd
(
int
thresholdTime
,
int
l
evel
,
String
className
,
String
methodName
,
String
desc
)
{
recodeObjectMethodCostEnd
(
thresholdTime
,
l
evel
,
className
,
methodName
,
desc
,
new
StaicMethodObject
());
public
void
recodeStaticMethodCostEnd
(
int
thresholdTime
,
int
currentL
evel
,
String
className
,
String
methodName
,
String
desc
)
{
recodeObjectMethodCostEnd
(
thresholdTime
,
currentL
evel
,
className
,
methodName
,
desc
,
new
StaicMethodObject
());
}
private
void
jsonTravel
(
List
<
MethodStackBean
>
methodStackBeans
,
List
<
MethodInvokNode
>
methodInvokNodes
)
{
...
...
@@ -254,7 +213,7 @@ public class MethodStackUtil {
public
void
toJson
()
{
List
<
MethodStackBean
>
methodStackBeans
=
new
ArrayList
<>();
for
(
MethodInvokNode
methodInvokNode
:
ROOT_METHOD_STACKS
.
values
())
{
for
(
MethodInvokNode
methodInvokNode
:
METHOD_STACKS
.
get
(
0
)
.
values
())
{
MethodStackBean
methodStackBean
=
new
MethodStackBean
();
methodStackBean
.
setCostTime
(
methodInvokNode
.
getCostTimeMillis
());
methodStackBean
.
setFunction
(
methodInvokNode
.
getClassName
()
+
"&"
+
methodInvokNode
.
getMethodName
());
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitManagerAdapter.kt
浏览文件 @
28b07296
...
...
@@ -28,7 +28,7 @@ class DokitManagerAdapter(kitViews: MutableList<KitWrapItem>?)
override
fun
convert
(
holder
:
BaseViewHolder
,
item
:
KitWrapItem
)
{
when
(
item
.
itemType
)
{
KitWrapItem
.
TYPE_TITLE
->
{
item
.
name
?
.
let
{
item
.
name
.
let
{
holder
.
getView
<
TextView
>(
R
.
id
.
tv_title_name
).
text
=
it
}
}
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitManagerFragment.kt
浏览文件 @
28b07296
...
...
@@ -343,7 +343,7 @@ class DokitManagerFragment : BaseFragment() {
}
mAdapter
.
setOnItemClickListener
{
adapter
,
view
,
position
->
mAdapter
.
setOnItemClickListener
{
_
,
_
,
position
->
if
(
IS_EDIT
)
{
val
multiKitItem
=
mKits
[
position
]
if
(
multiKitItem
.
itemType
==
KitWrapItem
.
TYPE_KIT
)
{
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitSettingAdapter.kt
浏览文件 @
28b07296
...
...
@@ -18,6 +18,6 @@ class DokitSettingAdapter(datas: MutableList<String>)
:
BaseQuickAdapter
<
String
,
BaseViewHolder
>(
R
.
layout
.
dk_item_main_setting
,
datas
)
{
override
fun
convert
(
holder
:
BaseViewHolder
,
name
:
String
)
{
holder
.
getView
<
TextView
>(
R
.
id
.
tv_name
).
setText
(
name
)
holder
.
getView
<
TextView
>(
R
.
id
.
tv_name
).
text
=
name
}
}
\ No newline at end of file
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/DokitSettingFragment.kt
浏览文件 @
28b07296
...
...
@@ -45,7 +45,7 @@ class DokitSettingFragment : BaseFragment() {
mAdapter
=
DokitSettingAdapter
(
mSettings
)
setting_list
.
adapter
=
mAdapter
setting_list
.
layoutManager
=
LinearLayoutManager
(
activity
)
mAdapter
.
setOnItemClickListener
{
adapter
,
view
,
position
->
mAdapter
.
setOnItemClickListener
{
_
,
_
,
position
->
when
(
position
)
{
0
->
{
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/ToolPanelAdapter.kt
浏览文件 @
28b07296
...
...
@@ -42,7 +42,7 @@ class ToolPanelAdapter(kitViews: MutableList<KitWrapItem>?)
override
fun
convert
(
holder
:
BaseViewHolder
,
item
:
KitWrapItem
)
{
when
(
item
.
itemType
)
{
KitWrapItem
.
TYPE_TITLE
->
{
item
.
name
?
.
let
{
item
.
name
.
let
{
if
(
it
.
equals
(
DokitUtil
.
getString
(
R
.
string
.
dk_category_platform
)))
{
holder
.
getView
<
TextView
>(
R
.
id
.
tv_sub_title_name
).
visibility
=
View
.
VISIBLE
holder
.
getView
<
TextView
>(
R
.
id
.
tv_sub_title_name
).
text
=
"(www.dokit.cn)"
...
...
@@ -64,7 +64,7 @@ class ToolPanelAdapter(kitViews: MutableList<KitWrapItem>?)
val
radioGroup
=
holder
.
getView
<
RadioGroup
>(
R
.
id
.
rb_group
)
val
rbNormal
=
holder
.
getView
<
RadioButton
>(
R
.
id
.
rb_normal
)
val
rbSystem
=
holder
.
getView
<
RadioButton
>(
R
.
id
.
rb_system
)
radioGroup
.
setOnCheckedChangeListener
{
group
,
checkedId
->
radioGroup
.
setOnCheckedChangeListener
{
_
,
checkedId
->
if
(
checkedId
==
R
.
id
.
rb_normal
)
{
//选中normal
SharedPrefsUtil
.
putString
(
SharedPrefsKey
.
FLOAT_START_MODE
,
"normal"
)
...
...
Android/doraemonkit/src/main/java/com/didichuxing/doraemonkit/kit/toolpanel/ToolPanelDokitView.kt
浏览文件 @
28b07296
...
...
@@ -114,7 +114,7 @@ class ToolPanelDokitView : AbsDokitView() {
4
}
}
mAdapter
.
setOnItemClickListener
{
adapter
,
view
,
position
->
mAdapter
.
setOnItemClickListener
{
_
,
_
,
position
->
val
multiKitItem
=
mKits
[
position
]
if
(
multiKitItem
.
itemType
==
KitWrapItem
.
TYPE_KIT
)
{
//常规模式下点击常用工具不隐藏工具面板
...
...
Android/gradle.properties
浏览文件 @
28b07296
...
...
@@ -16,3 +16,5 @@ android.debug.obsoleteApi=true
android.useAndroidX
=
true
android.enableJetifier
=
true
android.injected.testOnly
=
false
#dokit 函数调用栈层级
DoKit_MethodStack_Level
=
8
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录