Android gradle外掛列印時間戳
在效能調優時經常要列印函式執行時間、引數值等, 為了除錯加了很多程式碼,調完後還要刪掉, 這個事很繁瑣。 我們可以用Android Profiler或methodtracing列印函式執行時間,但日誌太多了且缺少引數值。所以JakeWharton寫了個hugo庫, 是用AspectJ實現的,基於AOP思想。 我看了hugo原始碼,總共四個檔案左右,程式碼量很少。
我想做個同功能的外掛,順便學習一下gradle外掛製作方法和位元組碼注入。
用法很簡單,參考 ofollow,noindex">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實現的。
@DebugLogger 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); } }
執行程式:

日誌.png
原理:
註解的作用表示要修改哪個函式, gradle外掛的作用是遍歷.class, Javassist是位元組碼注入工具。
在編譯期間進行位元組碼注入, 開啟./app/build/intermediates/classes/debug/transforms/TPTransform/1目錄可以看到修改後的位元組碼。

注入位元組碼.png
優點:在編譯期間注入業務邏輯程式碼,比在原始碼里加log更方便,不用feature時只要配置gradle 外掛不參與編譯即可。
展望:在編譯期間加日誌只是一個點, 還可以實現很多其它業務邏輯。
完整程式碼: https://github.com/brycegao/TimePlugin 求star