美文网首页
gradle插件字节码插桩(四),Activity里注入代码

gradle插件字节码插桩(四),Activity里注入代码

作者: 和平菌 | 来源:发表于2017-11-13 14:56 被阅读0次

    向Activity的onCreate方法里注入一个Toast

    第三篇修改class文件的时候我们没有具体去修改class文件,后来发现修改class文件的时候还存在一些问题,所以这里再总结一下:

    private static void injectClass(String className, String path) {
            CtClass c = pool.getCtClass(className)
            if (c.isFrozen()) {
                c.defrost()
            }
    
            /**这里进行操作*/
           if(isActivity(activities, c)){
                injectActivityLifeCircle(c)
            }
          
    
            c.writeFile(path)
            c.detach()
        }
    
    
     private static void injectActivityLifeCircle(CtClass c){
            System.out.println("注入Activity文件" + c.getName())
    
            if(c != null){
                CtMethod onCreateMethod = c.getDeclaredMethod("onCreate")
    
    
                String insetAfterStr = "android.widget.Toast.makeText(this,\"我是被插入的Toast代码~!!\",android.widget.Toast.LENGTH_SHORT).show(); " //在方法开头插入代码
    
                try {
                    onCreateMethod.insertAfter(insetAfterStr)
                } catch (Exception e){
                    e.printStackTrace()
                }
    
                System.out.println("注入Toast...................................")
    
            }
    
        }
    
    

    一开始我是上面这样写的,但是运行的时候就会报错。

    后来查资料发现需要android的类库,并且要引入Bundle的包,所以需要在getDeclaredMethod("onCreate")之前加入下面的代码

    ···
    pool.appendClassPath(project.android.bootClasspath[0].toString());
    pool.importPackage("android.os.Bundle");
    ···

    然后运行不报错了,但是一直没有插入代码。

    千辛万苦,最终才发现,Groovy申明字符串的时候有一个三引号,于是就试了一下把字符串的申明改成了

    String insetAfterStr = """ android.widget.Toast.makeText(this,"我是被插入的Toast代码~!!",android.widget.Toast.LENGTH_SHORT).show(); """ 
    

    于是在三引号的包裹下,终于字节码插桩成功了。

    接下来面临的就是业务方面的问题了。

    相关文章

      网友评论

          本文标题:gradle插件字节码插桩(四),Activity里注入代码

          本文链接:https://www.haomeiwen.com/subject/iqtzmxtx.html