在性能調優時經常要列印函數執行時間、參數值等, 為了調試加了很多代碼,調完後還要删掉, 這個事很繁瑣。 我們可以用Android Profiler或methodtracing列印函數執行時間,但日志太多了且缺少參數值。是以JakeWharton寫了個hugo庫, 是用AspectJ實作的,基于AOP思想。 我看了hugo源碼,總共四個檔案左右,代碼量很少。
我想做個同功能的插件,順便學習一下gradle插件制作方法和位元組碼注入; 版本上傳到bintray.com。
用法很簡單,參考
https://github.com/brycegao/TimePlugin/tree/master/demo 項目build.gradle檔案裡添加classpath和maven。buildscript {
repositories {
google()
jcenter()
maven { url "https://dl.bintray.com/brycegmail/maven" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.brycegao.timeplugin:timeplugin:1.0.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://dl.bintray.com/brycegmail/maven" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
在app子產品的build.gradle檔案添加
apply plugin: 'timeplugin'
...
implementation 'com.brycegao.tpannotation:tpannotation:1.0.2'
想列印日志的類或方法前添加注解@DebugLogger即可,用法參照hugo實作的。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showMsg(1, "this is test");
findViewById(R.id.btn_next).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
private void showMsg(int i, String msg) {
try {
Thread.sleep(100); //僅僅為了測試
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
}
}```
運作程式

原理:
注解的作用表示要修改哪個函數, gradle插件的作用是周遊.class, Javassist是位元組碼注入工具。
在編譯期間進行位元組碼注入, 打開./app/build/intermediates/classes/debug/transforms/TPTransform/1目錄可以看到修改後的位元組碼。

優點:在編譯期間注入業務邏輯代碼,比在源碼裡加log更友善,不用feature時隻要配置gradle 插件不參與編譯即可。
展望:在編譯期間加日志隻是一個點, 還可以實作很多其它業務邏輯。