提交 2bfaffa0 编写于 作者: J jackjintai

android: 函数耗时调用栈

上级 f80fd499
......@@ -99,13 +99,12 @@ dependencies {
implementation rootProject.ext.dependencies["weex_sdk"]
implementation rootProject.ext.dependencies["utilcode"]
implementation rootProject.ext.dependencies["easypermissions"]
implementation rootProject.ext.dependencies["epic"]
releaseImplementation rootProject.ext.dependencies["okgo"]
//高德地图定位
implementation rootProject.ext.dependencies["amap_location"]
//腾讯地图定位
implementation rootProject.ext.dependencies["tencent_location"]
debugImplementation rootProject.ext.dependencies["leakcanary-android"]
//debugImplementation rootProject.ext.dependencies["leakcanary-android"]
//百度地图定位
implementation files('libs/BaiduLBS_Android.jar')
// implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.12'
......
......@@ -4,14 +4,14 @@ if (rootProject.ext.config["applyPlugin"]) {
// 这里引用正常库
dependencies {
//外部平台依赖
debugImplementation project(":doraemonkit")
//debugImplementation project(":doraemonkit")
//debugImplementation project(":doraemonkit-weex")
releaseImplementation project(":doraemonkit-no-op")
//releaseImplementation project(":doraemonkit-no-op")
//releaseImplementation project(":doraemonkit-weex-no-op")
//新版线上包
// debugImplementation "com.didichuxing.doraemonkit:doraemonkit:${rootProject.ext.android["jcenterArchivesVersionName"]}"
debugImplementation "com.didichuxing.doraemonkit:doraemonkit:${rootProject.ext.android["jcenterArchivesVersionName"]}"
// debugImplementation "com.didichuxing.doraemonkit:doraemonkit-leakcanary:${rootProject.ext.android["jcenterArchivesVersionName"]}"
// releaseImplementation "com.didichuxing.doraemonkit:doraemonkit-no-op:${rootProject.ext.android["jcenterArchivesVersionName"]}"
releaseImplementation "com.didichuxing.doraemonkit:doraemonkit-no-op:${rootProject.ext.android["jcenterArchivesVersionName"]}"
// debugImplementation "com.didichuxing.doraemonkit:doraemonkit-weex:${rootProject.ext.android["jcenterArchivesVersionName"]}"
// releaseImplementation "com.didichuxing.doraemonkit:doraemonkit-weex-no-op:${rootProject.ext.android["jcenterArchivesVersionName"]}"
......
......@@ -12,8 +12,6 @@ import com.didichuxing.doraemonkit.DoraemonKit
import com.didichuxing.doraemonkit.kit.AbstractKit
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.taobao.android.dexposed.DexposedBridge
import com.taobao.android.dexposed.XC_MethodHook
import java.util.*
/**
......@@ -41,13 +39,6 @@ class App : Application() {
intent.putExtra(WebViewActivity.KEY_URL, url)
startActivity(intent)
}
DexposedBridge.findAndHookMethod(Thread::class.java, "run", object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
Log.i(TAG, "param==>${param.toString()}")
}
})
//严格检查模式
//StrictMode.enableDefaults();
}
......
......@@ -4,12 +4,16 @@ buildscript {
repositories {
google()
jcenter()
maven {
//本地插件地址
url uri(rootProject.ext.config["localRepoURL"])
}
}
dependencies {
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.2"
//classpath "com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.ext.android["kotlin_version"]}"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......@@ -20,7 +24,10 @@ allprojects {
repositories {
google()
jcenter()
maven {
//本地插件地址
url uri(rootProject.ext.config["localRepoURL"])
}
}
}
......
......@@ -17,12 +17,13 @@ ext {
//app版本号
versionCode : 313,
//dokit 插件版本号
pluginVersionName : "3.1.3",
pluginVersionName : "3.1.4",
//jcenter dokit版本号 打包上传时 dokit的版本名字
jcenterArchivesVersionName: "3.1.3",
//didi内部仓库版本号
didiArchivesVersionName : "1000.0.22",
versionName : "3.1.3",
//didiArchivesVersionName : "1000.0.22",
didiArchivesVersionName : "3.1.3",
versionName : "3.1.4",
glide_version : "4.9.0",
kotlin_version : "1.3.61"
]
......
package com.didichuxing.doraemonkit.plugin;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.transform.DokitApplicationTransform;
import com.didichuxing.doraemonkit.plugin.transform.DokitBigImageTransform;
import com.didichuxing.doraemonkit.plugin.transform.DokitCommTransform;
import com.didichuxing.doraemonkit.plugin.transform.DokitSlowMethodTransform;
......@@ -46,7 +47,8 @@ public final class DoKitPlugin implements Plugin<Project> {
}
});
//Application启动查找
appExtension.registerTransform(new DokitApplicationTransform(project), Collections.EMPTY_LIST);
//普通的插装
appExtension.registerTransform(new DokitCommTransform(project), Collections.EMPTY_LIST);
//urlConnection代理到OkHttp
......
package com.didichuxing.doraemonkit.plugin;
import java.util.List;
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2020/4/21-20:50
* 描 述:
* 修订历史:
* ================================================
*/
public class MethodStackNode {
private int Level = 0;
private int childSize = 0;
private String className;
private String methodName;
private List<MethodStackNode> children;
public int getLevel() {
return Level;
}
public void setLevel(int level) {
Level = level;
}
public int getChildSize() {
if (children == null) {
return 0;
}
return children.size();
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public List<MethodStackNode> getChildren() {
return children;
}
public void setChildren(List<MethodStackNode> children) {
this.children = children;
}
}
package com.didichuxing.doraemonkit.plugin.bytecode;
import com.didichuxing.doraemonkit.plugin.DokitExtUtil;
import com.didichuxing.doraemonkit.plugin.StringUtils;
import com.didichuxing.doraemonkit.plugin.bytecode.method.application.ApplicationOnCreateMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.AmapLocationMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.BaiduLocationMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.FlagMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.OkHttpMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.PlatformHttpMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.TencentLocationMethodAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.method.comm.TencentLocationSingleMethodAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import javax.swing.tree.TreeNode;
/**
* Created by jint on 13/12/2019.
* 类访问器
*/
public final class DokitApplicationClassAdapter extends ClassVisitor {
/**
* 当前类型
*/
private String className;
/**
* 当前类的父类 假如存在的话
*/
private String superName;
/**
* @param cv cv
*/
public DokitApplicationClassAdapter(final ClassVisitor cv) {
super(Opcodes.ASM7, cv);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
this.className = name;
this.superName = superName;
}
/**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor}
* instance (or {@literal null}) each time it is called, i.e., it should not return a previously
* returned visitor.
*
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
* the method is synthetic and/or deprecated.
* @param methodName the method's name.
* @param desc the method's descriptor (see {@link Type}).
* @param signature the method's signature. May be {@literal null} if the method parameters,
* return type and exceptions do not use generic types.
* @param exceptions the internal names of the method's exception classes (see {@link
* Type#getInternalName()}). May be {@literal null}.
* @return an object to visit the byte code of the method, or {@literal null} if this class
* visitor is not interested in visiting the code of this method.
*/
@Override
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
//开关被关闭 不插入代码
if (!DokitExtUtil.getInstance().isDokitPluginSwitch()) {
return mv;
}
//app启动hook点 onCreate()函数 兼容MultiDex
if (!StringUtils.isEmpty(superName) && (superName.equals("android/app/Application") || superName.equals("android/support/multidex/MultiDexApplication")) && methodName.equals("onCreate") && desc.equals("()V")) {
//log(className, access, methodName, desc, signature);
return mv == null ? null : new ApplicationOnCreateMethodAdapter(className, methodName, access, desc, mv);
}
//过滤所有类中当前方法中所有的字节码
return mv;
}
/**
* 获取形参个数
*
* @param desc
* @return
*/
private int getParamsSize(String desc) {
//(Landroid/app/Application;Ljava/util/List;Ljava/lang/String;)V 包含3个参数的install方法实例
if (desc == null || desc.equals("")) {
return 0;
}
//包含返回值 所以需要减1
return desc.split(";").length - 1;
}
/**
* 日志输出
*
* @param className
* @param access
* @param name
* @param desc
* @param signature
*/
private void log(String className, int access, String name, String desc, String signature) {
System.out.println("DokitApplicationClassAdapter=matched=>" + "className=" + className + " access=" + access + " methodName=" + name + " desc=" + desc + " signature=" + signature);
}
}
\ No newline at end of file
......@@ -24,7 +24,6 @@ public final class DokitUrlConnectionClassAdapter extends ClassVisitor {
*/
public DokitUrlConnectionClassAdapter(final ClassVisitor cv) {
super(Opcodes.ASM7, cv);
}
@Override
......@@ -60,7 +59,6 @@ public final class DokitUrlConnectionClassAdapter extends ClassVisitor {
}
//过滤所有类中当前方法中所有的字节码
return mv == null ? null : new UrlConnectionMethodAdapter(className, methodName, access, desc, mv);
}
......
package com.didichuxing.doraemonkit.plugin.bytecode.method.application;
import com.android.tools.r8.code.InvokeStatic;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Created by jint on 13/12/2019.
*/
public final class ApplicationOnCreateMethodAdapter extends LocalVariablesSorter implements Opcodes {
private String className;
private String methodName;
public ApplicationOnCreateMethodAdapter(String className, String methodName, int access, String desc, MethodVisitor mv) {
super(Opcodes.ASM7, access, desc, mv);
this.className = className;
this.methodName = methodName;
}
/**
* @param opcode 操作指令
* @param owner 调用对象
* @param name 函数名
* @param desc 函数签名
* @param isInterface 是否是接口
*/
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
//全局替换URL的openConnection方法为dokit的URLConnection
if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESTATIC) {
log(opcode, owner, name, desc, isInterface);
super.visitMethodInsn(opcode, owner, name, desc, isInterface);
//super.visitMethodInsn(INVOKESTATIC, "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil", "proxy", "(Ljava/net/URLConnection;)Ljava/net/URLConnection;", false);
} else {
super.visitMethodInsn(opcode, owner, name, desc, isInterface);
}
}
/**
* 日志输出
*
* @param opcode
* @param owner
* @param name
* @param desc
*/
private void log(int opcode, String owner, String name, String desc, boolean isInterface) {
System.out.println("ApplicationOnCreateMethodAdapter=matched=>" + " opcode=" + opcode + " owner=" + owner + " methodName=" + name + " desc=" + desc + " isInterface=" + isInterface);
System.out.println("");
}
}
package com.didichuxing.doraemonkit.plugin.transform;
import com.android.build.api.transform.Context;
import com.android.build.api.transform.TransformException;
import com.android.build.api.transform.TransformInput;
import com.android.build.api.transform.TransformOutputProvider;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.weaver.DokitApplicationWeaver;
import com.didichuxing.doraemonkit.plugin.weaver.DokitCommWeaver;
import com.quinn.hunter.transform.HunterTransform;
import com.quinn.hunter.transform.RunVariant;
import org.gradle.api.Project;
import java.io.IOException;
import java.util.Collection;
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2019-12-18-11:38
* 描 述:Dokit 字节码转换器
* 修订历史:
* ================================================
*/
public class DokitApplicationTransform extends HunterTransform {
private DokitExtension dokitExtension;
private String extensionName = "dokitExt";
private AppExtension appExtension;
public DokitApplicationTransform(Project project) {
super(project);
try {
this.appExtension = (AppExtension) project.getProperties().get("android");
//创建自动的代码
this.dokitExtension = (DokitExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver = new DokitApplicationWeaver(appExtension);
this.bytecodeWeaver.setExtension(dokitExtension);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return dokitExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return dokitExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.weaver;
import com.android.build.gradle.AppExtension;
import com.didichuxing.doraemonkit.plugin.DokitExtension;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitApplicationClassAdapter;
import com.didichuxing.doraemonkit.plugin.bytecode.DokitCommClassAdapter;
import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2019-12-13-14:01
* 描 述:dokit 通用weave
* 修订历史:
* ================================================
*/
public class DokitApplicationWeaver extends BaseWeaver {
private DokitExtension dokitExtension;
private AppExtension appExtension;
public DokitApplicationWeaver(AppExtension appExtension) {
this.appExtension = appExtension;
}
@Override
public void setExtension(Object extension) {
if (extension == null) {
return;
}
this.dokitExtension = (DokitExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new DokitApplicationClassAdapter(classWriter);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册