提交 d04c1886 编写于 作者: J jackjintai

modify:

1、新增asm aop方案
上级 417fec62
......@@ -21,12 +21,14 @@ android {
}
buildTypes {
debug {
debuggable true
minifyEnabled false
shrinkResources false
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
debuggable true
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.release
......@@ -62,9 +64,7 @@ dependencies {
implementation rootProject.ext.dependencies["multidex"]
implementation rootProject.ext.dependencies["appcompat-v7"]
implementation rootProject.ext.dependencies["design"]
//implementation rootProject.ext.dependencies["constraintLayout"]
implementation rootProject.ext.dependencies["okhttp"]
implementation rootProject.ext.dependencies["okio"]
implementation rootProject.ext.dependencies["glide"]
implementation rootProject.ext.dependencies["glide_okhttp3"]
annotationProcessor rootProject.ext.dependencies["glide_compiler"]
......@@ -74,4 +74,10 @@ dependencies {
//weex相关
implementation rootProject.ext.dependencies["weex_inspector"]
implementation rootProject.ext.dependencies["weex_sdk"]
implementation rootProject.ext.dependencies["utilcode"]
implementation rootProject.ext.dependencies["easypermissions"]
releaseImplementation rootProject.ext.dependencies["okgo"]
//高德地图定位
implementation rootProject.ext.dependencies["amap_location"]
}
if (rootProject.ext.config["applyPlugin"]) {
// 引用插件,插件会在编译期把DoraemonKit.install方法插入Application中,前提是用户必须实现自己的Application
apply plugin: 'android-aspectjx'
apply plugin: 'com.didi.dokit'
// 这里引用正常库
dependencies {
// debugImplementation project(":doraemonkit")
// debugImplementation project(":doraemonkit-leakcanary")
// debugImplementation project(":doraemonkit-aop")
// debugImplementation project(":doraemonkit_weex")
// releaseImplementation project(":doraemonkit-no-op")
// releaseImplementation project(":doraemonkit_weex_no_op")
debugImplementation project(":doraemonkit")
debugImplementation project(":doraemonkit-leakcanary")
debugImplementation project(":doraemonkit-weex")
releaseImplementation project(":doraemonkit-no-op")
releaseImplementation project(":doraemonkit-weex-no-op")
//新版线上包
// debugImplementation "com.didichuxing.doraemonkit:kit:${rootProject.ext.android["innerArchivesVersionName"]}"
// debugImplementation "com.didichuxing.doraemonkit:kit-leakcanary:${rootProject.ext.android["innerArchivesVersionName"]}"
// releaseImplementation "com.didichuxing.doraemonkit:kit-no-op:${rootProject.ext.android["innerArchivesVersionName"]}"
// debugImplementation "com.didichuxing.doraemonkit:kit-weex:${rootProject.ext.android["innerArchivesVersionName"]}"
// releaseImplementation "com.didichuxing.doraemonkit:kit-weex-no-op:${rootProject.ext.android["innerArchivesVersionName"]}"
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit:2.0.1'
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit-leakcanary:2.0.1'
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit-weex:2.0.1'
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit-aop:2.0.1'
releaseImplementation 'com.didichuxing.doraemonkit:doraemonkit-weex-no-op:2.0.1'
releaseImplementation 'com.didichuxing.doraemonkit:doraemonkit-no-op:2.0.1'
}
} else {
// 引用no-op的库
dependencies {
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.didichuxing.doraemondemo">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET" />
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--用于写入缓存数据到扩展存储卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!-- tools:replace问题参考 https://developer.android.google.cn/studio/build/manifest-merge?hl=zh-cn tools:replace部分-->
<application
android:name=".App"
android:allowBackup="false"
......@@ -12,7 +35,9 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/dk_app_icon"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:replace="android:allowBackup">
<activity android:name=".MainDebugActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......@@ -24,8 +49,16 @@
<activity android:name=".WebViewActivity" />
<activity android:name=".TestActivity" />
<activity android:name=".SecondActivity" />
</application>
<!-- 高德定位服务-->
<service android:name="com.amap.api.location.APSService" />
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="11f9728ee0c2a141663fc4b784c42a33" />
</application>
</manifest>
\ No newline at end of file
......@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".App"
android:allowBackup="false"
......@@ -17,8 +18,13 @@
<activity android:name=".WebViewActivity" />
<activity android:name=".TestActivity" />
<activity android:name=".SecondActivity" />
</application>
<!-- 高德定位服务-->
<service android:name="com.amap.api.location.APSService" />
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="11f9728ee0c2a141663fc4b784c42a33"></meta-data>
</application>
</manifest>
\ No newline at end of file
......@@ -3,10 +3,9 @@ package com.didichuxing.doraemondemo;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.StrictMode;
import android.support.multidex.MultiDex;
import com.didichuxing.doraemondemo.dokit.KitDemo;
import com.didichuxing.doraemondemo.dokit.DemoKit;
import com.didichuxing.doraemonkit.DoraemonKit;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.kit.webdoor.WebDoorManager;
......@@ -22,14 +21,14 @@ import java.util.List;
public class App extends Application {
private static final String TAG = "App";
@Override
public void onCreate() {
super.onCreate();
List<IKit> kits = new ArrayList<>();
kits.add(new KitDemo());
DoraemonKit.install(this, kits);
kits.add(new DemoKit());
DoraemonKit.install(this, kits, "0f2e4fc5540392a7083d61c921198c78");
Fresco.initialize(this);
DoraemonKit.setWebDoorCallback(new WebDoorManager.WebDoorCallback() {
@Override
public void overrideUrlLoading(Context context, String url) {
......@@ -40,7 +39,24 @@ public class App extends Application {
}
});
//严格检查模式
StrictMode.enableDefaults();
//StrictMode.enableDefaults();
// try {
// test1();
// } catch (Exception e) {
// e.printStackTrace();
// }
// StackTraceElement[] stack = new Throwable().getStackTrace();
// for (StackTraceElement stackTraceElement : stack) {
// Log.d(TAG, "----> " + stackTraceElement.toString());
//
// }
}
private void test1() {
throw new NullPointerException("空指针异常");
}
@Override
......
......@@ -11,7 +11,6 @@ public class SecondActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
......@@ -3,8 +3,8 @@ package com.didichuxing.doraemondemo.dokit;
import android.content.Context;
import com.didichuxing.doraemondemo.R;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.ui.base.DokitIntent;
import com.didichuxing.doraemonkit.ui.base.DokitViewManager;
......@@ -17,7 +17,7 @@ import com.didichuxing.doraemonkit.ui.base.DokitViewManager;
* 修订历史:
* ================================================
*/
public class KitDemo implements IKit {
public class DemoKit extends AbstractKit {
@Override
public int getCategory() {
return Category.BIZ;
......
......@@ -19,6 +19,13 @@
android:text="当前编译环境"
android:textSize="18sp" />
<Button
android:id="@+id/btn_jump"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="跳转" />
<Button
android:id="@+id/btn_trace"
android:layout_width="match_parent"
......@@ -26,10 +33,17 @@
android:text="函数调用耗时" />
<Button
android:id="@+id/btn_jump"
android:id="@+id/btn_location"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="跳转" />
android:text="获取位置信息(系统)" />
<Button
android:id="@+id/btn_location_amap"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="获取位置信息(高德)" />
<Button
android:id="@+id/btn_load_img"
......@@ -106,28 +120,28 @@
<Button
android:id="@+id/btn_test_urlconnection"
android:id="@+id/btn_okhttp_mock"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="HttpUrlConnection Test" />
android:text="OkHttp Mock" />
<Button
android:id="@+id/btn_test_okhttp"
android:id="@+id/btn_connection_mock"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="OkHttp Test" />
android:text="HttpURLConnection Mock" />
<!-- <Button-->
<!-- android:id="@+id/btn_test_gps"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="50dp"-->
<!-- android:text="gps Test(必须先打开位置模拟)" />-->
<Button
android:id="@+id/btn_rpc_mock"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Didi Rpc Mock" />
<Button
android:id="@+id/btn_test_custom"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="其他网络库 Test" />
android:text="其他网络库(自定义抓包)" />
<Button
android:id="@+id/btn_show_hide_icon"
......@@ -135,11 +149,6 @@
android:layout_height="50dp"
android:text="显示/隐藏入口" />
<Button
android:id="@+id/btn_time_count"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="页面跳转耗时" />
<Button
android:id="@+id/btn_test_crash"
......
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
apply from: "config.gradle"
repositories {
google()
jcenter()
//阿里云的镜像库
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
maven { url 'https://www.jitpack.io' }
maven {
//本地插件地址
url uri('./plugins')
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.novoda:bintray-release:0.9.1'
classpath 'com.github.franticn:gradle_plugin_android_aspectjx:2.0.6'
classpath 'com.didichuxing.doraemonkit:doraemonkit-plugin:0.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
......@@ -23,8 +24,8 @@ allprojects {
repositories {
google()
jcenter()
//阿里云的镜像
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
//北京maven
maven { url 'http://artifactory.intra.xiaojukeji.com/artifactory/public/' }
maven { url 'https://www.jitpack.io' }
}
......@@ -34,5 +35,5 @@ task clean(type: Delete) {
delete rootProject.buildDir
}
tasks.getByPath(":doraemonkit:javadocRelease").enabled = false
tasks.getByPath(":doraemonkit-no-op:javadocRelease").enabled = false
//tasks.getByPath(":doraemonkit:javadocRelease").enabled = false
//tasks.getByPath(":doraemonkit-no-op:javadocRelease").enabled = false
......@@ -2,62 +2,83 @@ ext {
config = [
// 很多app都会有自己的打包开关,来区分线上包和测试包,可以通过给applyPlugin赋值来区分测试包和线上包
// 线上包不会接入DoraemonKit,测试包会自动接入
applyPlugin : true,
applyPlugin : true,
//上传到远程仓库时需要打开
uploadArchives: true,
uploadArchives : false,
//是否发布插件到远程仓库
publishPluginToRemote: false
]
android = [compileSdkVersion : 28,
suppotrSdkVersion : "27.1.1",
applicationId : "com.didichuxing.doraemondemo",
minSdkVersion : 16,
targetSdkVersion : 27,
versionCode : 201,
versionCode : 210,
//滴滴内网dokit版本号
innerArchivesVersionName : "0.1.23",
innerArchivesVersionName : "0.2.0",
//dokit 插件版本号
pluginVersionName : "0.1.0",
//jcenter dokit版本号
jcenterArchivesVersionName: "2.0.1",
versionName : "2.0.1",
"glide" : "4.8.0",
jcenterArchivesVersionName: "1.2.7",
versionName : "2.1.0",
glide : "4.8.0",
]
dependencies = [// ###### android library start ######
"multidex" : "com.android.support:multidex:1.0.3",
"annotations" : "com.android.support:support-annotations:${android["suppotrSdkVersion"]}",
"support-v4" : "com.android.support:support-v4:${android["suppotrSdkVersion"]}",
"appcompat-v7" : "com.android.support:appcompat-v7:${android["suppotrSdkVersion"]}",
"support-v13" : "com.android.support:support-v13:${android["suppotrSdkVersion"]}",
"cardview-v7" : "com.android.support:cardview-v7:${android["suppotrSdkVersion"]}",
"recyclerview-v7" : "com.android.support:recyclerview-v7:${android["suppotrSdkVersion"]}",
"design" : "com.android.support:design:${android["suppotrSdkVersion"]}",
"gridlayout-v7" : "com.android.support:gridlayout-v7:${android["suppotrSdkVersion"]}",
"multidex" : "com.android.support:multidex:1.0.3",
"annotations" : "com.android.support:support-annotations:${android["suppotrSdkVersion"]}",
"support-v4" : "com.android.support:support-v4:${android["suppotrSdkVersion"]}",
"appcompat-v7" : "com.android.support:appcompat-v7:${android["suppotrSdkVersion"]}",
"support-v13" : "com.android.support:support-v13:${android["suppotrSdkVersion"]}",
"cardview-v7" : "com.android.support:cardview-v7:${android["suppotrSdkVersion"]}",
"recyclerview-v7" : "com.android.support:recyclerview-v7:${android["suppotrSdkVersion"]}",
"design" : "com.android.support:design:${android["suppotrSdkVersion"]}",
"gridlayout-v7" : "com.android.support:gridlayout-v7:${android["suppotrSdkVersion"]}",
//constraintLayout
"constraintLayout" : "com.android.support.constraint:constraint-layout:1.1.3",
"constraintLayout" : "com.android.support.constraint:constraint-layout:1.1.3",
//test
"junit" : "junit:junit:4.12",
"junit" : "junit:junit:4.12",
//第三方
"guava" : "com.google.guava:guava:27.1-android",
"guava" : "com.google.guava:guava:27.1-android",
//表格
//"SmartTable" : 'com.github.huangyanbin:SmartTable:2.2.0',
"okhttp" : "com.squareup.okhttp3:okhttp:3.12.1",
"okio" : "com.squareup.okio:okio:1.15.0",
"utilcode" : 'com.blankj:utilcode:1.25.9',
"glide" : 'com.github.bumptech.glide:glide:4.9.0',
"glide_okhttp3" : "com.github.bumptech.glide:okhttp3-integration:4.9.0",
"glide_compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"picasso" : 'com.squareup.picasso:picasso:2.71828',
"fresco" : 'com.facebook.fresco:fresco:1.13.0',
"fresco-processors" : "jp.wasabeef:fresco-processors:2.1.0",
"rootbeer-lib" : 'com.scottyab:rootbeer-lib:0.0.7',
"gson" : 'com.google.code.gson:gson:2.8.2',
"zxing" : 'com.google.zxing:core:3.3.0',
"free_reflection" : 'me.weishu:free_reflection:2.1.0',
"leakcanary-android" : 'com.squareup.leakcanary:leakcanary-android:1.6.3',
"leakcanary-android-no-op" : 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3',
"haha" : 'com.squareup.haha:haha:2.0.4',
"gradle-android-plugin-aspectjx": 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.6',
"debug-db" : "com.amitshekhar.android:debug-db:1.0.6",
"debug-db-encrypt" : "com.amitshekhar.android:debug-db-encrypt:1.0.6",
"doraemonkit" : "com.didichuxing.doraemonkit:doraemonkit:${android["jcenterArchivesVersionName"]}",
"weex_inspector" : "com.taobao.android:weex_inspector:0.24.2.11",
"weex_sdk" : "com.taobao.android:weex_sdk:0.26.0",
//暂时不支持3.14.0以上的okhttp版本
"okhttp" : "com.squareup.okhttp3:okhttp:3.12.1",
//将urlconnection代理到okhttp
//"okhttp_urlconnection" : "com.squareup.okhttp3:okhttp-urlconnection:3.12.1",
//"okio" : "com.squareup.okio:okio:1.15.0",
"utilcode" : 'com.blankj:utilcode:1.25.9',
"glide" : 'com.github.bumptech.glide:glide:4.9.0',
"glide_okhttp3" : "com.github.bumptech.glide:okhttp3-integration:4.9.0",
"glide_compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"picasso" : 'com.squareup.picasso:picasso:2.71828',
"fresco" : 'com.facebook.fresco:fresco:1.13.0',
"fresco-processors" : "jp.wasabeef:fresco-processors:2.1.0",
"rootbeer-lib" : 'com.scottyab:rootbeer-lib:0.0.7',
"gson" : 'com.google.code.gson:gson:2.8.2',
"zxing" : 'com.google.zxing:core:3.3.0',
"free_reflection" : 'me.weishu:free_reflection:2.1.0',
"leakcanary-android" : 'com.squareup.leakcanary:leakcanary-android:1.6.3',
"leakcanary-android-no-op": 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3',
"haha" : 'com.squareup.haha:haha:2.0.4',
"debug-db" : "com.amitshekhar.android:debug-db:1.0.6",
"debug-db-encrypt" : "com.amitshekhar.android:debug-db-encrypt:1.0.6",
"doraemonkit" : "com.didichuxing.doraemonkit:doraemonkit:${android["jcenterArchivesVersionName"]}",
"weex_inspector" : "com.taobao.android:weex_inspector:0.24.2.11",
"weex_sdk" : "com.taobao.android:weex_sdk:0.26.0",
"brvah" : 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50',
"easy_refresh_layout" : 'com.github.anzaizai:EasyRefreshLayout:1.3.1',
"jsonviewer" : "com.yuyh.json:jsonviewer:1.0.6",
"room_runtime" : 'android.arch.persistence.room:runtime:1.1.1',
"room_compile" : 'android.arch.persistence.room:compiler:1.1.1',
"um_analytics" : 'com.umeng.umsdk:analytics:8.0.0',
"um_common" : 'com.umeng.umsdk:common:2.0.0',
"didi_http" : 'com.didichuxing.foundation:http:2.1.0.74',
"didi_rpc" : 'com.didichuxing.foundation:rpc:2.1.0.74',
"okgo" : "com.lzy.net:okgo:3.0.4",
//高德定位
"amap_location" : 'com.amap.api:location:latest.integration',
"tencent_location" : 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.2.4',
"easypermissions" : "pub.devrel:easypermissions:2.0.1"
]
}
apply plugin: 'com.android.library'
apply plugin: 'android-aspectjx'
apply from: 'upload.gradle'
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode rootProject.ext.android["versionCode"]
versionName rootProject.ext.android["versionName"]
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
compileOnly project(":doraemonkit")
compileOnly rootProject.ext.dependencies["okhttp"]
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.didichuxing.doraemonkit.aop"/>
package parking.didi.com.aop;
import com.didichuxing.doraemonkit.kit.network.NetworkManager;
import com.didichuxing.doraemonkit.kit.network.httpurlconnection.proxy.HttpUrlConnectionProxy;
import com.didichuxing.doraemonkit.kit.network.httpurlconnection.proxy.HttpsUrlConnectionProxy;
import com.didichuxing.doraemonkit.kit.network.okhttp.DoraemonInterceptor;
import com.didichuxing.doraemonkit.kit.network.okhttp.DoraemonWeakNetworkInterceptor;
import com.didichuxing.doraemonkit.kit.network.okhttp.LargePictureInterceptor;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import javax.net.ssl.HttpsURLConnection;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
/**
* @desc:
*/
public class AopUtils {
public static URLConnection URLOpenConnection(URLConnection connection) {
if (!NetworkManager.isActive()) {
return connection;
}
if (connection instanceof HttpsURLConnection) {
return new HttpsUrlConnectionProxy((HttpsURLConnection) connection);
} else if (connection instanceof HttpURLConnection) {
return new HttpUrlConnectionProxy((HttpURLConnection) connection);
} else {
return connection;
}
}
public static void addInterceptor(OkHttpClient.Builder builder) {
// 判断当前是否已经添加了拦截器,如果已添加则返回
for (Interceptor interceptor : builder.interceptors()) {
if (interceptor instanceof DoraemonInterceptor) {
return;
}
}
builder.addNetworkInterceptor(new DoraemonWeakNetworkInterceptor())
//添加大图检测拦截器
.addInterceptor(new LargePictureInterceptor())
.addInterceptor(new DoraemonInterceptor());
}
}
package parking.didi.com.aop;
import android.app.Application;
import android.util.Log;
import com.didichuxing.doraemonkit.DoraemonKit;
import com.didichuxing.doraemonkit.kit.timecounter.TimeCounterManager;
import com.didichuxing.doraemonkit.util.LogHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* 通用的hooker
*/
@Aspect
public class DoraemonHooker {
public static final String TAG = "DoraemonHooker";
/**
* @param proceedingJoinPoint
* @throws Throwable
* @Around 完全替代目标方法执行
*/
@Around("execution(* android.app.Application.onCreate(..))")
public void install(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Log.v(TAG, "hook application.onCreate start");
TimeCounterManager.get().onAppCreateStart();
//执行原有方法
proceedingJoinPoint.proceed();
// Application app = (Application) proceedingJoinPoint.getTarget();
// DoraemonKit.install(app);
TimeCounterManager.get().onAppCreateEnd();
Log.v(TAG, "hook application.onCreate end");
}
}
\ No newline at end of file
package parking.didi.com.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import java.net.URLConnection;
@Aspect
public class HttpUrlAspect {
private static final String TAG = "HttpUrlAspect";
@Around("call(* java.net.URL.openConnection(..))")
public URLConnection URLOpenConnection(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
URLConnection connection = (URLConnection) proceedingJoinPoint.proceed();
return AopUtils.URLOpenConnection(connection);
}
}
\ No newline at end of file
package parking.didi.com.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import okhttp3.OkHttpClient;
@Aspect
public class OkHttpAspect {
private static final String TAG = "OkHttpAspect";
@After("execution(okhttp3.OkHttpClient.Builder.new(..))")
public void addInterceptor(JoinPoint joinPoint) {
AopUtils.addInterceptor((OkHttpClient.Builder) joinPoint.getTarget());
}
}
\ No newline at end of file
<resources>
<string name="dk_app_name">doraemonkit_aop</string>
</resources>
apply plugin: 'com.novoda.bintray-release'
// 配置发布
publish {
def groupProjectID = 'com.didichuxing.doraemonkit'
def artifactProjectID = 'doraemonkit-aop'
def publishVersionID = "${rootProject.ext.android["jcenterArchivesVersionName"]}"
userOrg = 'doraemonkit'
repoName = 'DoraemonKit'
groupId = groupProjectID
artifactId = artifactProjectID
publishVersion = publishVersionID
desc = '{library description}'
website = '{github_url}'
}
\ No newline at end of file
......@@ -3,8 +3,8 @@ package com.didichuxing.doraemonkit.kit.leakcanary;
import android.content.Context;
import android.content.Intent;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.squareup.leakcanary.R;
import com.squareup.leakcanary.internal.DisplayLeakActivity;
......@@ -17,7 +17,7 @@ import com.squareup.leakcanary.internal.DisplayLeakActivity;
* 修订历史:
* ================================================
*/
public class LeakCanaryKit implements IKit {
public class LeakCanaryKit extends AbstractKit {
@Override
public int getCategory() {
return Category.PERFORMANCE;
......
......@@ -34,7 +34,7 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
//implementation rootProject.ext.dependencies["appcompat-v7"]
compileOnly rootProject.ext.dependencies["okio"]
//compileOnly rootProject.ext.dependencies["okio"]
compileOnly rootProject.ext.dependencies["okhttp"]
//三大图片框架
compileOnly rootProject.ext.dependencies["glide"]
......
......@@ -6,6 +6,8 @@ import android.app.Application;
import com.bumptech.glide.manager.LifecycleListener;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.kit.webdoor.WebDoorManager;
import com.didichuxing.doraemonkit.ui.base.DokitIntent;
import com.didichuxing.doraemonkit.ui.base.DokitViewManager;
import java.util.List;
......@@ -27,6 +29,7 @@ public class DoraemonKit {
}
public static void install(final Application app) {
}
......@@ -34,13 +37,24 @@ public class DoraemonKit {
}
public static void show(Activity activity) {
public static void install(final Application app, List<IKit> selfKits, String productId) {
}
public static void show() {
}
public static void hide() {
}
/**
* 直接显示工具面板页面
*/
public static void showToolPanel() {
}
public static boolean isShow() {
return false;
}
......
package com.didichuxing.doraemonkit.kit;
import android.content.Context;
/**
* ================================================
* 作 者:jint(金台)
* 版 本:1.0
* 创建日期:2019-11-20-15:29
* 描 述:
* 修订历史:
* ================================================
*/
public abstract class AbstractKit implements IKit {
/**
* 启动UniversalActivity
*
* @param context
* @param fragmentIndex
*/
public void startUniversalActivity(Context context, int fragmentIndex) {
}
}
......@@ -39,7 +39,7 @@ public abstract class AbsDokitView implements DokitView,TouchProxy.OnTouchEventL
private Handler mHandler;
/**
* 当前FloatPopViewName 用来当做map的key 和popViewIntent的tag一致
* 当前dokitViewName 用来当做map的key 和dokitViewIntent的tag一致
*/
private Bundle mBundle;
......@@ -236,7 +236,7 @@ public abstract class AbsDokitView implements DokitView,TouchProxy.OnTouchEventL
}
/**
* 将当前popview于activity解绑
* 将当前dokitview于activity解绑
*/
public void detach() {
......
......@@ -5,7 +5,7 @@ import android.os.Bundle;
/**
* Created by jintai on 2019/9/16.
* popView intent
* dokitView intent
*/
public class DokitIntent {
......
......@@ -73,12 +73,12 @@ interface DokitView {
void initDokitViewLayoutParams(DokitViewLayoutParams params);
/**
* app进入后台时调用 内置popview 不需要实现
* app进入后台时调用 内置dokitView 不需要实现
*/
void onEnterBackground();
/**
* app回到前台时调用 内置popview 不需要实现
* app回到前台时调用 内置dokitView 不需要实现
*/
void onEnterForeground();
......
......@@ -49,7 +49,7 @@ public class DokitViewManager implements DokitViewManagerInterface {
/**
* 只有普通浮标才会调用
* 保存每种类型popView的位置
* 保存每种类型dokitView的位置
*/
public void saveDokitViewPos(String tag, int marginLeft, int marginTop) {
......@@ -58,7 +58,7 @@ public class DokitViewManager implements DokitViewManagerInterface {
/**
* 只有普通的浮标才需要调用
* 添加activity关联的所有popView activity resume的时候回调
* 添加activity关联的所有dokitView activity resume的时候回调
*
* @param activity
*/
......@@ -78,7 +78,7 @@ public class DokitViewManager implements DokitViewManagerInterface {
}
/**
* 隐藏工具列表popView
* 隐藏工具列表dokitView
*/
public void detachToolPanel() {
......@@ -101,7 +101,7 @@ public class DokitViewManager implements DokitViewManagerInterface {
}
/**
* 移除所有activity的所有popView
* 移除所有activity的所有dokitView
*/
@Override
public void detachAll() {
......
......@@ -46,7 +46,7 @@ public interface DokitViewManagerInterface {
void detach(Class<? extends Object> dokitViewClass);
/**
* 移除所有activity的所有popView
* 移除所有activity的所有dokitView
*/
void detachAll();
......@@ -90,7 +90,7 @@ public interface DokitViewManagerInterface {
/**
* 只有普通的浮标才需要调用
* 添加activity关联的所有popView activity resume的时候回调
* 添加activity关联的所有dokitView activity resume的时候回调
*
* @param activity
*/
......
apply plugin: 'groovy'
apply from: 'upload.gradle'
dependencies {
implementation gradleApi()
implementation localGroovy()
//版本不能太高 否则会跟项目的as版本冲突
implementation 'com.android.tools.build:gradle:3.0.0'
implementation 'com.android.tools.build:gradle-api:3.0.0'
implementation 'commons-io:commons-io:2.6'
implementation 'commons-codec:commons-codec:1.11'
//noinspection GradleDependency
implementation 'org.ow2.asm:asm:7.2'
//noinspection GradleDependency
implementation 'org.ow2.asm:asm-util:7.2'
//noinspection GradleDependency
implementation 'org.ow2.asm:asm-commons:7.2'
implementation 'com.quinn.hunter:hunter-transform:0.9.3'
//高德定位
compileOnly rootProject.ext.dependencies["amap_location"]
}
repositories {
google()
jcenter()
mavenCentral()
}
package com.didichuxing.doraemonkit.plugin;
import com.android.build.gradle.AppExtension;
import com.android.build.gradle.internal.dsl.BuildType;
import com.didichuxing.doraemonkit.plugin.amap.AmapTransform;
import com.didichuxing.doraemonkit.plugin.debug_flag.FlagTransform;
import com.didichuxing.doraemonkit.plugin.okhttp.OkHttpTransform;
import com.didichuxing.doraemonkit.plugin.platformhttp.PlatformHttpTransform;
import com.didichuxing.doraemonkit.plugin.urlconnection.UrlConnectionTransform;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import java.util.Collections;
import java.util.List;
/**
* 调试准备
* 调试前执行./gradlew clean -Dorg.gradle.daemon=false -Dorg.gradle.debug=true命令
* ,然后按debug按钮,接着执行task debug便会生效
*/
public final class DoraemonKitPlugin implements Plugin<Project> {
@SuppressWarnings("NullableProblems")
@Override
public void apply(Project project) {
AppExtension appExtension = (AppExtension) project.getProperties().get("android");
List<String> taskNames = project.getGradle().getStartParameter().getTaskNames();
//如果task包含release 则不进行字节码替换
for (String taskName : taskNames) {
if (taskName.contains("Release")) {
return;
}
}
appExtension.registerTransform(new FlagTransform(project), Collections.EMPTY_LIST);
appExtension.registerTransform(new OkHttpTransform(project), Collections.EMPTY_LIST);
appExtension.registerTransform(new PlatformHttpTransform(project), Collections.EMPTY_LIST);
appExtension.registerTransform(new UrlConnectionTransform(project), Collections.EMPTY_LIST);
appExtension.registerTransform(new AmapTransform(project), Collections.EMPTY_LIST);
}
}
package com.didichuxing.doraemonkit.plugin.amap;
import com.quinn.hunter.transform.RunVariant;
/**
* Created by Quinn on 07/10/2018.
*/
public class AmapExtension {
public RunVariant runVariant = RunVariant.DEBUG;
public boolean duplcatedClassSafeMode = false;
@Override
public String toString() {
return "FlagExtension{" +
"runVariant=" + runVariant +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
'}';
}
}
package com.didichuxing.doraemonkit.plugin.amap;
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.didichuxing.doraemonkit.plugin.amap.bytecode.AmapWeaver;
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;
/**
* Created by jint on 13/12/2019.
*/
public final class AmapTransform extends HunterTransform {
private Project project;
private AmapExtension mAMapExtension;
private String extensionName = "amapExt";
public AmapTransform(Project project) {
super(project);
this.project = project;
//创建指定扩展
project.getExtensions().create(extensionName, AmapExtension.class);
//创建自动的代码
this.bytecodeWeaver = new AmapWeaver();
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
mAMapExtension = (AmapExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver.setExtension(mAMapExtension);
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return mAMapExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return mAMapExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.amap.bytecode;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Created by jint on 13/12/2019.
* 类访问器
*/
public final class AmapClassAdapter extends ClassVisitor {
private String className;
/**
* @param cv 传进来的是 ClassWriter
*/
AmapClassAdapter(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);
className = name;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
//判断指定并且类中的方法类型
if (className.equals("com/amap/api/location/AMapLocationClient") && name.equals("setLocationListener")) {
//创建MethodVisitor代理
System.out.println("className===>" + className + " descriptor====>" + desc + " name===>" + name);
return mv == null ? null : new AmapMethodAdapter(access, desc, mv);
}
return mv;
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.plugin.amap.bytecode;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
import java.lang.reflect.Modifier;
/**
* Only weave com/didichuxing/doraemonkit/aop/OkHttpHook installInterceptor method
* Created by jint on 13/12/2019.
*/
public final class AmapMethodAdapter extends LocalVariablesSorter implements Opcodes {
AmapMethodAdapter(int access, String desc, MethodVisitor mv) {
super(Opcodes.ASM7, access, desc, mv);
}
@Override
public void visitCode() {
//在AMapLocationClient的setLocationListener方法之中插入自定义代理回调类
mv.visitTypeInsn(NEW, "com/didichuxing/doraemonkit/aop/AMapLocationListenerProxy");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "com/didichuxing/doraemonkit/aop/AMapLocationListenerProxy", "<init>", "(Lcom/amap/api/location/AMapLocationListener;)V", false);
mv.visitVarInsn(ASTORE, 1);
super.visitCode();
}
}
package com.didichuxing.doraemonkit.plugin.amap.bytecode;
import com.didichuxing.doraemonkit.plugin.amap.AmapExtension;
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
* 描 述:
* 修订历史:
* ================================================
*/
public class AmapWeaver extends BaseWeaver {
private AmapExtension flagExtension;
@Override
public void setExtension(Object extension) {
if (extension == null) {
return;
}
this.flagExtension = (AmapExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new AmapClassAdapter(classWriter);
}
}
package com.didichuxing.doraemonkit.plugin.debug_flag;
import com.quinn.hunter.transform.RunVariant;
/**
* Created by Quinn on 07/10/2018.
*/
public class FlagExtension {
public RunVariant runVariant = RunVariant.DEBUG;
public boolean duplcatedClassSafeMode = false;
@Override
public String toString() {
return "FlagExtension{" +
"runVariant=" + runVariant +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
'}';
}
}
package com.didichuxing.doraemonkit.plugin.debug_flag;
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.didichuxing.doraemonkit.plugin.debug_flag.bytecode.FlagWeaver;
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;
/**
* Created by jint on 13/12/2019.
*/
public final class FlagTransform extends HunterTransform {
private Project project;
private FlagExtension flagExtension;
private String extensionName = "debugExt";
public FlagTransform(Project project) {
super(project);
this.project = project;
//创建指定扩展
project.getExtensions().create(extensionName, FlagExtension.class);
//创建自动的代码
this.bytecodeWeaver = new FlagWeaver();
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
flagExtension = (FlagExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver.setExtension(flagExtension);
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return flagExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return flagExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.debug_flag.bytecode;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Only weave com/didichuxing/doraemonkit/aop/OkHttpHook installInterceptor method
* Created by jint on 13/12/2019.
*/
public final class FlagMethodAdapter extends LocalVariablesSorter implements Opcodes {
FlagMethodAdapter(int access, String desc, MethodVisitor mv) {
super(Opcodes.ASM7, access, desc, mv);
}
@Override
public void visitCode() {
//在installInterceptor 方法之前插入IS_HOOK = true 的代码
mv.visitInsn(ICONST_1);
mv.visitFieldInsn(PUTSTATIC, "com/didichuxing/doraemonkit/DoraemonKit", "IS_HOOK", "Z");
super.visitCode();
}
}
package com.didichuxing.doraemonkit.plugin.debug_flag.bytecode;
import com.didichuxing.doraemonkit.plugin.debug_flag.FlagExtension;
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
* 描 述:
* 修订历史:
* ================================================
*/
public class FlagWeaver extends BaseWeaver {
private FlagExtension flagExtension;
@Override
public void setExtension(Object extension) {
if (extension == null) {
return;
}
this.flagExtension = (FlagExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new FlageClassAdapter(classWriter);
}
}
package com.didichuxing.doraemonkit.plugin.debug_flag.bytecode;
import org.gradle.internal.impldep.org.apache.http.util.TextUtils;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Created by jint on 13/12/2019.
* 类访问器
*/
public final class FlageClassAdapter extends ClassVisitor {
private String className;
/**
* @param cv 传进来的是 ClassWriter
*/
FlageClassAdapter(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);
className = name;
}
/**
* @param access
* @param name
* @param desc 方法参数类型
* @param signature
* @param exceptions
* @return
*/
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
//判断指定并且类中的方法类型
if (className.equals("com/didichuxing/doraemonkit/DoraemonKit") && name.equals("install") && desc != null) {
//(Landroid/app/Application;Ljava/util/List;Ljava/lang/String;)V 包含3个参数的install方法
String[] descs = desc.split(";");
if (descs.length == 4) {
System.out.println("className===>" + className + " descriptor====>" + desc + " name===>" + name);
//创建MethodVisitor代理
return mv == null ? null : new FlagMethodAdapter(access, desc, mv);
} else {
return mv;
}
}
return mv;
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.plugin.okhttp;
import com.quinn.hunter.transform.RunVariant;
/**
* Created by Quinn on 07/10/2018.
*/
public class OkHttpExtension {
public RunVariant runVariant = RunVariant.DEBUG;
public boolean weaveEventListener = true;
public boolean duplcatedClassSafeMode = false;
@Override
public String toString() {
return "OkHttpHunterExtension{" +
"runVariant=" + runVariant +
", weaveEventListener=" + weaveEventListener +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
'}';
}
}
package com.didichuxing.doraemonkit.plugin.okhttp;
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.didichuxing.doraemonkit.plugin.okhttp.bytecode.OkHttpWeaver;
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;
/**
* Created by Quinn on 09/09/2018.
*/
public final class OkHttpTransform extends HunterTransform {
private Project project;
private OkHttpExtension okHttpHunterExtension;
private String extensionName = "okHttpExt";
public OkHttpTransform(Project project) {
super(project);
this.project = project;
//创建指定扩展
project.getExtensions().create(extensionName, OkHttpExtension.class);
//创建自动的代码
this.bytecodeWeaver = new OkHttpWeaver();
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
okHttpHunterExtension = (OkHttpExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver.setExtension(okHttpHunterExtension);
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return okHttpHunterExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return okHttpHunterExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.okhttp.bytecode;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.File;
/**
* Created by Quinn on 09/09/2018.
* 类访问器
*/
public final class OkHttpClassAdapter extends ClassVisitor {
private String className;
private boolean weaveEventListener;
/**
* @param cv 传进来的是 ClassWriter
* @param weaveEventListener
*/
OkHttpClassAdapter(final ClassVisitor cv, boolean weaveEventListener) {
super(Opcodes.ASM7, cv);
this.weaveEventListener = weaveEventListener;
}
@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;
}
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
//判断指定并且类中的方法类型
if (className.equals("okhttp3/OkHttpClient$Builder") && name.equals("<init>")) {
//创建MethodVisitor代理
System.out.println("className===>" + className + "desc====>" + desc + " name===>" + name);
return mv == null ? null : new OkHttpMethodAdapter(access, desc, mv, weaveEventListener);
}
return mv;
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.plugin.okhttp.bytecode;
import com.android.build.gradle.internal.LoggerWrapper;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Only weave okhttp3/OkHttpClient's init method
* Created by Quinn on 09/09/2018.
*/
public final class OkHttpMethodAdapter extends LocalVariablesSorter implements Opcodes {
private static final LoggerWrapper logger = LoggerWrapper.getLogger(OkHttpMethodAdapter.class);
private boolean weaveEventListener;
OkHttpMethodAdapter(int access, String desc, MethodVisitor mv, boolean weaveEventListener) {
super(Opcodes.ASM7, access, desc, mv);
this.weaveEventListener = weaveEventListener;
}
@Override
public void visitInsn(int opcode) {
//添加全局的 Dokit Interceptor
if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
//
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "okhttp3/OkHttpClient$Builder", "interceptors", "Ljava/util/List;");
mv.visitFieldInsn(GETSTATIC, "com/didichuxing/doraemonkit/aop/OkHttpHook", "globalInterceptors", "Ljava/util/List;");
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
mv.visitInsn(POP);
}
super.visitInsn(opcode);
}
}
package com.didichuxing.doraemonkit.plugin.okhttp.bytecode;
import com.didichuxing.doraemonkit.plugin.okhttp.OkHttpExtension;
import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
/**
* Created by 金台 on 12/12/2019.
*
*/
public final class OkHttpWeaver extends BaseWeaver {
private OkHttpExtension okHttpHunterExtension;
@Override
public void setExtension(Object extension) {
if (extension == null) return;
this.okHttpHunterExtension = (OkHttpExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new OkHttpClassAdapter(classWriter, this.okHttpHunterExtension.weaveEventListener);
}
}
package com.didichuxing.doraemonkit.plugin.platformhttp;
import com.quinn.hunter.transform.RunVariant;
/**
* Created by Quinn on 07/10/2018.
*/
public class PlatformHttpExtension {
public RunVariant runVariant = RunVariant.DEBUG;
public boolean weaveEventListener = true;
public boolean duplcatedClassSafeMode = false;
@Override
public String toString() {
return "OkHttpHunterExtension{" +
"runVariant=" + runVariant +
", weaveEventListener=" + weaveEventListener +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
'}';
}
}
package com.didichuxing.doraemonkit.plugin.platformhttp;
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.didichuxing.doraemonkit.plugin.platformhttp.bytecode.PlatformHttpWeaver;
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;
/**
* Created by Quinn on 09/09/2018.
*/
public final class PlatformHttpTransform extends HunterTransform {
private Project project;
private PlatformHttpExtension okHttpHunterExtension;
private String extensionName = "platformHttpExt";
public PlatformHttpTransform(Project project) {
super(project);
this.project = project;
//创建指定扩展
project.getExtensions().create(extensionName, PlatformHttpExtension.class);
//创建自动的代码
this.bytecodeWeaver = new PlatformHttpWeaver();
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
okHttpHunterExtension = (PlatformHttpExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver.setExtension(okHttpHunterExtension);
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return okHttpHunterExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return okHttpHunterExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.platformhttp.bytecode;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Created by Quinn on 09/09/2018.
* 类访问器
*/
public final class PlatformHttpClassAdapter extends ClassVisitor {
private String className;
private boolean weaveEventListener;
/**
* @param cv 传进来的是 ClassWriter
* @param weaveEventListener
*/
PlatformHttpClassAdapter(final ClassVisitor cv, boolean weaveEventListener) {
super(Opcodes.ASM7, cv);
this.weaveEventListener = weaveEventListener;
}
@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;
}
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
//判断指定并且类中的方法类型
if (className.equals("didihttp/DidiHttpClient$Builder") && name.equals("<init>")) {
//创建MethodVisitor代理
System.out.println("className===>" + className + "desc====>" + desc + " name===>" + name);
return mv == null ? null : new PlatformHttpMethodAdapter(access, desc, mv, weaveEventListener);
}
return mv;
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.plugin.platformhttp.bytecode;
import com.android.build.gradle.internal.LoggerWrapper;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Only weave okhttp3/OkHttpClient's init method
* Created by Quinn on 09/09/2018.
*/
public final class PlatformHttpMethodAdapter extends LocalVariablesSorter implements Opcodes {
private boolean weaveEventListener;
PlatformHttpMethodAdapter(int access, String desc, MethodVisitor mv, boolean weaveEventListener) {
super(Opcodes.ASM7, access, desc, mv);
this.weaveEventListener = weaveEventListener;
}
@Override
public void visitInsn(int opcode) {
//添加全局的 platform Interceptor
if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
//
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "didihttp/DidiHttpClient$Builder", "interceptors", "Ljava/util/List;");
mv.visitFieldInsn(GETSTATIC, "com/didichuxing/foundation/net/rpc/http/PlatformHttpHook", "globalInterceptors", "Ljava/util/List;");
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
mv.visitInsn(POP);
}
super.visitInsn(opcode);
}
}
package com.didichuxing.doraemonkit.plugin.platformhttp.bytecode;
import com.didichuxing.doraemonkit.plugin.platformhttp.PlatformHttpExtension;
import com.quinn.hunter.transform.asm.BaseWeaver;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
/**
* Created by 金台 on 12/12/2019.
*
*/
public final class PlatformHttpWeaver extends BaseWeaver {
private PlatformHttpExtension okHttpHunterExtension;
@Override
public void setExtension(Object extension) {
if (extension == null) return;
this.okHttpHunterExtension = (PlatformHttpExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new PlatformHttpClassAdapter(classWriter, this.okHttpHunterExtension.weaveEventListener);
}
}
package com.didichuxing.doraemonkit.plugin.urlconnection;
import com.quinn.hunter.transform.RunVariant;
/**
* Created by Quinn on 07/10/2018.
*/
public class UrlConnectionExtension {
public RunVariant runVariant = RunVariant.DEBUG;
public boolean duplcatedClassSafeMode = false;
@Override
public String toString() {
return "FlagExtension{" +
"runVariant=" + runVariant +
", duplcatedClassSafeMode=" + duplcatedClassSafeMode +
'}';
}
}
package com.didichuxing.doraemonkit.plugin.urlconnection;
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.didichuxing.doraemonkit.plugin.urlconnection.bytecode.UrlConnectionWeaver;
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;
/**
* Created by jint on 13/12/2019.
*/
public final class UrlConnectionTransform extends HunterTransform {
private Project project;
private UrlConnectionExtension urlConnectionExtension;
private String extensionName = "urlConnectionExt";
public UrlConnectionTransform(Project project) {
super(project);
this.project = project;
//创建指定扩展
project.getExtensions().create(extensionName, UrlConnectionExtension.class);
//创建自动的代码
this.bytecodeWeaver = new UrlConnectionWeaver();
}
@Override
public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
urlConnectionExtension = (UrlConnectionExtension) project.getExtensions().getByName(extensionName);
this.bytecodeWeaver.setExtension(urlConnectionExtension);
super.transform(context, inputs, referencedInputs, outputProvider, isIncremental);
}
@Override
protected RunVariant getRunVariant() {
return urlConnectionExtension.runVariant;
}
@Override
protected boolean inDuplcatedClassSafeMode() {
return urlConnectionExtension.duplcatedClassSafeMode;
}
}
package com.didichuxing.doraemonkit.plugin.urlconnection.bytecode;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Created by jint on 13/12/2019.
* 类访问器
*/
public final class UrlConnectionClassAdapter extends ClassVisitor {
private String className;
/**
* @param cv 传进来的是 ClassWriter
*/
UrlConnectionClassAdapter(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);
className = name;
}
/**
* @param access
* @param name
* @param desc 方法参数类型
* @param signature
* @param exceptions
* @return
*/
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
//从传进来的ClassWriter中读取MethodVisitor
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
//创建MethodVisitor代理
return mv == null ? null : new UrlConnectionMethodAdapter(access, desc, mv);
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.plugin.urlconnection.bytecode;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
/**
* Only weave com/didichuxing/doraemonkit/aop/OkHttpHook installInterceptor method
* Created by jint on 13/12/2019.
*/
public final class UrlConnectionMethodAdapter extends LocalVariablesSorter implements Opcodes {
UrlConnectionMethodAdapter(int access, String desc, MethodVisitor mv) {
super(Opcodes.ASM7, access, desc, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
//全局替换URL的openConnection方法为dokit的URLConnection
if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/net/URL")
&& name.equals("openConnection") && desc.equals("()Ljava/net/URLConnection;")) {
System.out.println("===UrlConnectionMethodAdapter====openConnection=======");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/net/URL", "openConnection", "()Ljava/net/URLConnection;", false);
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);
}
}
}
package com.didichuxing.doraemonkit.plugin.urlconnection.bytecode;
import com.didichuxing.doraemonkit.plugin.urlconnection.UrlConnectionExtension;
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
* 描 述:
* 修订历史:
* ================================================
*/
public class UrlConnectionWeaver extends BaseWeaver {
private UrlConnectionExtension flagExtension;
@Override
public void setExtension(Object extension) {
if (extension == null) {
return;
}
this.flagExtension = (UrlConnectionExtension) extension;
}
@Override
protected ClassVisitor wrapClassWriter(ClassWriter classWriter) {
//返回指定的ClassVisitor
return new UrlConnectionClassAdapter(classWriter);
}
}
#入口文件
#文件名为插件名 即 apply plugin "xxx"
implementation-class=com.didichuxing.doraemonkit.plugin.DoraemonKitPlugin
\ No newline at end of file
def isRemote = rootProject.ext.config["publishPluginToRemote"]
if (isRemote) {
apply plugin: 'com.novoda.bintray-release'
// 配置发布
publish {
def groupProjectID = 'com.didichuxing.doraemonkit'
def artifactProjectID = 'doraemonkit-plugin'
def publishVersionID = "${rootProject.ext.android["pluginVersionName"]}"
userOrg = 'doraemonkit'
repoName = 'DoraemonKit'
groupId = groupProjectID
artifactId = artifactProjectID
publishVersion = publishVersionID
desc = '{library description}'
website = '{github_url}'
}
} else {
apply plugin: 'maven'
group = 'com.didichuxing.doraemonkit'
version = rootProject.ext.android["pluginVersionName"]
def localRepoURL = uri('../plugins')
uploadArchives {
repositories {
mavenDeployer {
repository(url: localRepoURL)
}
}
}
}
......@@ -3,15 +3,15 @@ package com.didichuxing.doraemonkit.weex.devtool;
import android.content.Context;
import android.content.Intent;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.weex.R;
/**
* @author haojianglong
* @date 2019-06-11
*/
public class DevToolKit implements IKit {
public class DevToolKit extends AbstractKit {
@Override
public int getCategory() {
......
......@@ -2,8 +2,8 @@ package com.didichuxing.doraemonkit.weex.info;
import android.content.Context;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.weex.R;
import com.didichuxing.doraemonkit.weex.common.DKCommonActivity;
......@@ -11,7 +11,7 @@ import com.didichuxing.doraemonkit.weex.common.DKCommonActivity;
* @author haojianglong
* @date 2019-06-11
*/
public class WeexInfoKit implements IKit {
public class WeexInfoKit extends AbstractKit {
@Override
public int getCategory() {
......
package com.didichuxing.doraemonkit.weex.log;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.didichuxing.doraemonkit.kit.logInfo.LogInfoDokitView;
import com.didichuxing.doraemonkit.kit.logInfo.LogLine;
import com.didichuxing.doraemonkit.ui.widget.titlebar.HomeTitleBar;
import com.didichuxing.doraemonkit.ui.widget.titlebar.TitleBar;
import com.didichuxing.doraemonkit.weex.R;
import java.util.ArrayList;
......@@ -19,26 +24,29 @@ import java.util.List;
public class WeexLogInfoDokitView extends LogInfoDokitView {
private final String WEEX_TAG = "weex";
FrameLayout mHomeTitleBar;
@Override
public View onCreateView(Context context, FrameLayout view) {
return LayoutInflater.from(context).inflate(R.layout.dk_weex_float_log_info, null);
}
@Override
public void initView() {
super.initView();
findViewById(R.id.title_bar).setVisibility(View.GONE);
LinearLayout rootView = findViewById(R.id.log_page);
HomeTitleBar homeTitleBar = new HomeTitleBar(getContext());
homeTitleBar.setBackgroundColor(getResources().getColor(R.color.foreground_wtf));
homeTitleBar.setTitle(getResources().getString(R.string.dk_console_log_title));
homeTitleBar.setIcon(R.drawable.dk_close_icon);
homeTitleBar.setListener(new HomeTitleBar.OnTitleBarClickListener() {
@Override
public void onRightClick() {
detach();
}
});
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
(int) getResources().getDimension(R.dimen.dk_home_title_height));
rootView.addView(homeTitleBar, 0, params);
mHomeTitleBar = findViewById(R.id.dokit_title_bar);
if (mHomeTitleBar instanceof HomeTitleBar) {
((HomeTitleBar) mHomeTitleBar).setListener(new HomeTitleBar.OnTitleBarClickListener() {
@Override
public void onRightClick() {
detach();
}
});
}
}
@Override
......
......@@ -2,18 +2,17 @@ package com.didichuxing.doraemonkit.weex.log;
import android.content.Context;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.ui.base.DokitIntent;
import com.didichuxing.doraemonkit.ui.base.DokitViewManager;
import com.didichuxing.doraemonkit.weex.R;
import com.didichuxing.doraemonkit.weex.common.DKCommonActivity;
/**
* @author haojianglong
* @date 2019-06-11
*/
public class WeexLogKit implements IKit {
public class WeexLogKit extends AbstractKit {
@Override
public int getCategory() {
......
......@@ -2,8 +2,8 @@ package com.didichuxing.doraemonkit.weex.storage;
import android.content.Context;
import com.didichuxing.doraemonkit.kit.AbstractKit;
import com.didichuxing.doraemonkit.kit.Category;
import com.didichuxing.doraemonkit.kit.IKit;
import com.didichuxing.doraemonkit.weex.R;
import com.didichuxing.doraemonkit.weex.common.DKCommonActivity;
......@@ -11,7 +11,7 @@ import com.didichuxing.doraemonkit.weex.common.DKCommonActivity;
* @author haojianglong
* @date 2019-06-11
*/
public class StorageKit implements IKit {
public class StorageKit extends AbstractKit {
@Override
public int getCategory() {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册