2017年9月15日,饿了么母公司拉扎斯集团发内部邮件,宣布饿了么和百度外卖继8月24日合并后的首轮架构调整通知。根据该通知,出任百度外卖新CEO的是魏海,负责百度外卖业务及双品牌战略落地工作。根据公开资料,魏海在饿了么的职位是商业分析副总裁。而百度外卖原CEO巩振兵担任百度外卖董事长,负责集团及百度外卖战略布局及关键业务梳理;百度外卖其他管理层人员任用保持不变。
作者简介短暂的休息回到了周一,新的一周努力起来!
本篇来自 刘镓旗 的投稿,分享了 git 和 Android Studio 有效结合相关的内容,希望大家喜欢!
刘镓旗 的博客地址:
写在前面http://blog.csdn.net/yulong0809/article/details/77752098?locationNum=9&fps=1
动态编译技术在开源框架中的应用非常的广泛,现在市面上的插件化框架,热修复框架几乎都使用了动态编译技术,原理几乎都是在编译期间动态的在class文件中注入代码或者或修改。那就让我们来了解一下这高大上的技术吧!
正文本章会以完成一个 demo 的形式来揭开动态编译的神秘面纱,将会分成三步
自定义 Gradle 插件
介绍 Transform API 及 实现步骤
实现在编译的过程中操作 .class 文件,对原有代码或者说逻辑进行一些处理,修改原 class 代码和动态生成 java 类
自定义gradle插件
在我们 app 下的 build.gradle 中的第一行是 apply plugin: ‘com.android.application’ ,其实这就是一个插件,是 google 写好的插件,我们自己写插一个插件也是这样引入,引入后我们的插件就会得到执行。
创建一个 module,什么样的都可以,不管是 Phone&Tablet Module 或 Android Librarty 都可以,然后只留下 src/main 和 build.gradle,其他的文件全部删除
在main 目录下创建 groovy 文件夹,然后在 groovy 目录下就可以创建我们的包名和groovy 文件了,记得后缀要已 .groovy 结尾。在这个文件中引入创建的包名,然后写一个 Class 继承于 Plugin< Project > 并重写 apply 方法。例如:
在 main 目录下创建 resources文件夹,继续在 resources下创建META-INF文件夹,继续在 META-INF 文件夹下创建 gradle-plugins 文件夹,最后在 gradle-plugins 文件夹下创建一个 xxx.properties 文件,注意:这个 xxx 就是在 app 下的 build.gradle 中引入时的名字,例如:apply plugin: ‘xxx’。在文件中写implementation-class=com.ljq.myreplugin.gradle.MyPlugin。
打开 build.gradle 删除里面所有的内容。然后格式按这个写,uploadArchives是上传到maven 库,然后执行 uploadArchives 这个 task,就将我们的这个插件打包上传到了本地maven 中,可以去本地的 Maven 库中查看
应用 gradle 插件:在项目下的 build.gradle(也可以在 module 中)中的 repositories 模块中定义本地 maven 库地址。在 dependencies 模块中引入我们的插件的路径,例:
最后在 module(app下的)下的 build.gradle 中引入插件,apply plugin: ‘my_replugin_gradle’ 这个名字是我们定义的 resource 文件下的那个.properties文件的名字,现在可以 clean 一下工程,然后在 Make 一下 ,可以在 Gradle Console 中看到我们的插件得到了执行,说明我们自定义的 Plugin 成功了。
还有一种简单的方式创建 gradle 插件,新建 module 时必须要把 module 的名称叫做 buildsrc,不需要再 main 下创建resources文件,在 gradle 插件的 build.gradle 中也不需要加入上传 maven 的代码,因为没有上传到 maven 中,所以在引入的时候项目 build.gradle 中也不需要加入 maven 库地址的代码。在app的module引入时直接写插件全类名就好,例如:apply plugin: com.ljq.myreplugin.gradle.MyPlugin。其他都和上边相同就好。
利用Google提供的Transform API 在编译的过程中操作.class文件
先说一下 Transform 是什么:
gradle 从1.5开始,gradle 插件包含了一个叫 Transform 的 API,这个 API 允许第三方插件在 class 文件转为为 dex 文件前操作编译好的 class 文件,这个 API 的目标是简化自定义类操作,而不必处理 Task,并且在操作上提供更大的灵活性。并且可以更加灵活地进行操作。 官方文档:
http://google.github.io/android-gradle-dsl/javadoc/
我们接着在上面的 demo 中继续完成使用 Transform API:
在我们自定义的 gradle 插件的 build.gradle 中引入 transform 的包,下面会进行代码注入,就一起引入的其他包
创建一个类继承 Transform 并实现其方法:
在我们自定义的 gradle 插件的 apply 方法中注册自定义的 Transform
使用Javassist实现在编译的过程中操作.class文件
使用 Javassist 实现在编译的过程中操作 .class 文件,动态注入代码 Javassist 是一个可以用来分析、编辑和创建 Java 字节码的开源类库对于语法和使用,请自行查阅资料。
我们知道 studio 会给我们创建一个 BuildConfig 的类,但是是否知道这个类是怎么生成的呢?下面我们来模拟一下 在 app 下的 build.gradle 下可以创建参数列表,然后将参数生成一个 java 类,在代码中就可以使用了
然后回到我们的自定义的 Plugin 中,贴一下整个代码
来看一下效果
下面我们利用 Transform 在 MainActivity 中动态的插入代码,先看一下现在的 MainAcitivity
可以看到上面的 setText 中使用的是我们上面动态生成的类中的字段,看一下怎么利用Transform 插入代码,先看一下 Transform 中代码
最重要生成代码在 MyInjects 类中,在这个类中我们传入了两个参数,一个是当前变量的文件夹,一个是当前的工程对象,来看一下代码
现在先 clean 一下项目,然后运行,代码就被插入了,看一下效果
到这里就完成了动态注入代码和动态生成 Java 类了,本文只是梳理原理和思路,至于高级的用法还请自行查阅资料
更多每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。
如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。
欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: