基于booster給方法套層try..catch (Demo)

如果不自己寫一個(gè)plugin插件的話旦万,可以現(xiàn)有開源庫比如Lancet或者AspectJ這兩個(gè)庫功能強(qiáng)大谜嫉,用于給方法套一層try...catch自然是輕而易舉萎坷,可以網(wǎng)上搜索下有很多的文章。

本文默認(rèn)你已經(jīng)熟悉了采用ASM實(shí)現(xiàn)gradle plugin 以及熟悉booster...

那么回到我們的話題上:自己如何使用ASM技術(shù)給方法套一層try...catch呢沐兰?
舉個(gè)例子哆档,如何給如下代碼中的printStr方法套一層try...catch呢?

public class HookTest {

    public void printStr(String s) {
        Log.i("HookTest", s);
    }
}

通過查看該方法對(duì)應(yīng)的字節(jié)碼:

     // 沒有套try..catch
     public printStr(Ljava/lang/String;)V
     LDC "HookTest"
     ALOAD 1
     INVOKESTATIC android/util/Log.i (Ljava/lang/String;Ljava/lang/String;)I
     POP
     RETURN
     MAXSTACK = 2
     MAXLOCALS = 2

     // 套try..catch之后
     public printStr(Ljava/lang/String;)V
     TRYCATCHBLOCK L0 L1 L2 java/lang/Exception
     L0
     LDC "HookTest"
     ALOAD 1
     INVOKESTATIC android/util/Log.i (Ljava/lang/String;Ljava/lang/String;)I
     POP
     L1
     GOTO L3
     L2
     ASTORE 2
     ALOAD 2
     INVOKEVIRTUAL java/lang/Exception.printStackTrace ()V
     L3
     RETURN

可以看到插入之后主要是多了對(duì)應(yīng)的try...catch的字節(jié)碼 以及多了一些L0..3住闯。

開始編寫代碼:
仍然是基于booster的框架進(jìn)行改造:

@AutoService(ClassTransformer::class)
class TestTryTransformer: ClassTransformer {
    override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
        val className = klass.name
        if (className == "com/remote/neacy/HookTest") {
            val method = klass.methods.find {
                "${it.name}${it.desc}" == "printStr(Ljava/lang/String;)V"
            }
            val start = LabelNode()
            val end = LabelNode()
            val catch = LabelNode()
            val returnLabelNode = LabelNode()
            // 定義try catch
            val tryNode = TryCatchBlockNode(start, end, catch, "java/lang/Exception")
            method?.tryCatchBlocks?.add(tryNode)
            method?.instructions?.iterator()?.asIterable()?.filter {
                it.opcode == Opcodes.RETURN
            }?.forEach {
                method.instructions?.apply {
                    // L0
                    insert(start)
                    // L1
                    insertBefore(it, end)
                    // goto L3
                    insertBefore(it, JumpInsnNode(Opcodes.GOTO, returnLabelNode))
                    // L2
                    insertBefore(it, catch)

                    insertBefore(it, VarInsnNode(Opcodes.ASTORE, 2))

                    insertBefore(it, VarInsnNode(Opcodes.ALOAD, 2))
                    // 調(diào)用方法 e.printStackTrace
                    insertBefore(it, MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Exception","printStackTrace", "()V", false))

                    insertBefore(it, returnLabelNode)
                }
            }
        }
        return super.transform(context, klass)
    }
}

本文主要是基于ASM中的Tree api瓜浸,參照字節(jié)碼寫起來還算順利。
最后比原,我們看下編譯出來的是不是想要的代碼:

public class HookTest {
    public HookTest() {
    }
    public void printStr(String s) {
        try {
            Log.i("HookTest", s);
        } catch (Exception var3) {
            var3.printStackTrace();
        }
    }
}

沒錯(cuò)了插佛,就是我們想要的結(jié)果。

由于本文只是簡(jiǎn)單的demo量窘,如果想要在自己項(xiàng)目中使用 可以增加配置文件如xxx類.xxx方法 或者 是通過注解的方式找到要套try..catch雇寇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绑改,隨后出現(xiàn)的幾起案子谢床,更是在濱河造成了極大的恐慌兄一,老刑警劉巖厘线,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異出革,居然都是意外死亡造壮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門骂束,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耳璧,“玉大人,你說我怎么就攤上這事展箱≈伎荩” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵混驰,是天一觀的道長攀隔。 經(jīng)常有香客問我,道長栖榨,這世上最難降的妖魔是什么昆汹? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮婴栽,結(jié)果婚禮上满粗,老公的妹妹穿的比我還像新娘。我一直安慰自己愚争,他們只是感情好映皆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布挤聘。 她就那樣靜靜地躺著,像睡著了一般捅彻。 火紅的嫁衣襯著肌膚如雪檬洞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天沟饥,我揣著相機(jī)與錄音添怔,去河邊找鬼。 笑死贤旷,一個(gè)胖子當(dāng)著我的面吹牛广料,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播幼驶,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼艾杏,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了盅藻?” 一聲冷哼從身側(cè)響起购桑,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎氏淑,沒想到半個(gè)月后勃蜘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡假残,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年缭贡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辉懒。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阳惹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出眶俩,到底是詐尸還是另有隱情莹汤,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布颠印,位于F島的核電站纲岭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嗽仪。R本人自食惡果不足惜荒勇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闻坚。 院中可真熱鬧沽翔,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至橘沥,卻和暖如春窗轩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背座咆。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工痢艺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人介陶。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓堤舒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哺呜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舌缤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容