android 插桩工具,Android Asm 插桩 教学项目
AndroidAutoTrack
本項目主要就是給大家一個參考學習的demo而已,主要是打算簡化學習gradle插件的成本,以及對于android transform的一次抽象,將增量更新等等進行一次抽象,以方便大家學習開發。
double tap plugin 雙擊優化
原理和無痕埋點相似,通過classvisitor的機制訪問所有View.OnClickListener的子類,然后插入雙擊優化的代碼塊。但是插入的是一個類,所以有一部分邏輯代碼,織入操作更為復雜,可以使用gradle插件去更好的學習。
InitBlockVisitor 這個類MethodVisitor會給當前類的init 添加一個成員變量。DoubleTapCheck doubleTap = new DoubleTapCheck(); 然后在onClick 方法前添加一個邏輯判斷。
使用原則
根目錄build 添加插件
buildscript {
repositories {
maven {
url "file://${rootDir.absolutePath}/.repo"
}
google()
jcenter()
}
dependencies {
classpath 'com.kronos.doubleTap:double_tap_plugin:0.1.3'
}
}
app 運行工程下引入插件 同時將你需要插入的代碼的className 和functionname 標記在Extension中
apply plugin: 'doubleTap'
doubleTab {
injectClassName = "com.a.doubleclickplugin.DoubleTapCheck"
injectFunctionName = "isNotDoubleTap"
}
直接編譯你的項目,觀察項目下的build/imtermediates/transform/DoubleTabTrasform/ 文件夾下面
如果有插入的代碼那么代表該插件已經編織代碼成功。
AutoTrackPlugin 安卓無痕埋點
通過編譯時檢索代碼中是否實現了View.OnClickListener接口,然后在onClick方法尾部插入代碼打點代碼。
如何將參數傳遞給打點代碼
View.OnClickListener listener=new View.OnClickListener() {
@Test
private Entity mdata;
@Override
public void onClick(View v) {
mdata = new Entity();
Log.i("MainActivity", v.toString());
Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
TODO
后續會補充上給fragment activity 生命周期方法補充增強
Thread Hook plugin 線程hook更換
通過字節碼訪問,查找項目內的線程池構造等,發現之后替換成自定義的線程構造。
方法
通過ASM的ClassNode 的方式讀取了當前類的所有構造函數,然后判斷當前的執行內容是否是需要變魔改的類,如果是則替換他的desc owner name相關。
class ThreadAsmHelper : AsmHelper {
@Throws(IOException::class)
override fun modifyClass(srcClass: ByteArray): ByteArray {
val classNode = ClassNode(Opcodes.ASM5)
val classReader = ClassReader(srcClass)
//1 將讀入的字節轉為classNode
classReader.accept(classNode, 0)
//2 對classNode的處理邏輯
val iterator: Iterator =
classNode.methods.iterator()
while (iterator.hasNext()) {
val method = iterator.next()
method.instructions?.iterator()?.forEach {
if (it.opcode == Opcodes.INVOKESTATIC) {
if (it is MethodInsnNode) {
it.hookExecutors(classNode, method)
}
}
}
}
val classWriter = ClassWriter(0)
//3 將classNode轉為字節數組
classNode.accept(classWriter)
return classWriter.toByteArray()
}
private fun MethodInsnNode.hookExecutors(classNode: ClassNode, methodNode: MethodNode) {
when (this.owner) {
EXECUTORS_OWNER -> {
info("owner:${this.owner} name:${this.name} ")
ThreadPoolCreator.poolList.forEach {
if (it.name == this.name && this.name == it.name && this.owner == it.owner) {
this.owner = Owner
this.name = it.methodName
this.desc = it.replaceDesc()
info("owner:${this.owner} name:${this.name} desc:${this.desc} ")
}
}
}
}
}
}
最后在編譯階段該類就會被替換成我們想要的類,舉個例子Executors.newSingleThreadExecutor();變更成TestIOThreadExecutor.getThreadPool();。
升級更新
多線程操作字節碼
base plugin 代碼升級,使用多線程優化,講字節碼操作執行在線程中,之后在主函數等待所有task執行完成之后在結束。
buildSrc 優化
通過buildSrc形式重構項目,不需要本地推aar,同時module可以被同一個buildSrc關聯上,方便調試和代碼上傳。
總結
以上是生活随笔為你收集整理的android 插桩工具,Android Asm 插桩 教学项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用c语言编程序输入一个正整数,编写一个程
- 下一篇: android addview指定位置,