OpenAtlas一款强大的Android非代理动态部署框架,目前已经处于稳定定状态。
与传统的代理方式插件不同,OpenAtlas需要对注册动态部署的组件到manifest文件。
初体验,只不过就是把程序跑起来,跑通,后面的路还很长。这个过程中也是遇到了不少问题,刚开始拿到这个项目真是无处下手(没有看到有wiki),后来百度搜索了下找到四篇博文,大概就是OpenAtlas的作者写的吧
后来,意外的发现项目上是有wiki的,真是想找块豆腐撞死算了
当然issues也可以当做学习的资料
基本上,能找的到的资源就这么多了
最后上一下项目主页地址
其实最早接触到Atlas也只是在一个多月前吧,当时去面试,面试官问我怎么动态加载dex,当时没听清楚,只是啊?了一下,他重复了一遍,说是65536方法数爆炸有没有遇到过,其实吧,说实话,真没遇到过,但是呢,就在那几天前在github上看到过这个问题,地址应该在这里Android应用方法数量超过65K个怎么办?,当时知道可以通过multi-dex来解决。面试完后自己回去搜了一下,最后发现方案很多,这里有总结Android 插件化 动态升级,然后这里是美团的解决方案美团Android DEX自动拆包及动态加载简介,Atlas最开始是在trinea的主页上看到的,一个优酷上的视频视频: 阿里技术沙龙第十六期《android插件化及动态部署—ATLAS 》伯奎,然后就去百度搜Atlas,结果很失望,搜不到这个东西。。。。后来去github上搜,无意间看到了OpenAtlas,粗粗瞄了一眼,感觉大概就是Atlas了,于是Star了该项目。知道最近,才开始研究这个东西。于是我就有问题了,这个OpenAtlas和淘宝的Atlas究竟有什么区别,就试着跑一个Demo试试看。这个过程也是有的艰苦的啊。。。。
首先从github上把核心项目下载下来https://github.com/bunnyblue/OpenAtlas和https://github.com/bunnyblue/OpenAtlasExtension, 原来的项目是eclipse和android studio都兼容的,个人有强迫症,强行把项目结构转化为了android studio的,转化完成后就是如图所示的结构,其实只是拷贝文件而已。
openatlasbundler是一个生成BundleList文件的java项目,转到android studio下新建的是java library项目,之后要修改下build.gradle
apply plugin: 'java'
apply plugin: 'application'
mainClassName='com.openAtlas.bundleInfo.maker.BundleMakeBooter'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
先把patch的aapt替换原来的,在..\OpenAtlasExtension\buildTools\binary\build.tool.R22\windows\aapt下找到aapt.exe,备份sdk目录..\sdk\build-tools\22.0.1中对应的aapt,将patch的aapt.exe移到该目录。
在app的module中,也就是宿主,增加依赖,依赖项目为openatlascore
compile project(':openatlascore')
新建一个类继承AtlasApp,在清单文件中指定该Application的name为该类。
新建一个module作为test plugin,注意包名以com开头,这个是因为这个库里面写死了是以libcom_开头的进行查找,也就是包名为com开头。我们将这个module中的清单文件中关于引用v7包中的资源删除,比如主题,也就是在清单文件中删除style属性,在style.xml中删除所有主题什申明。将v4,v7包以provided形式提供,
provided files('libs/android-support-v4.jar')
provided files('libs/android-support-v7-appcompat.jar')
至于原因么,v7包中的资源和类会在宿主中编译进去,插件不用编译进去。否则会报错的哟,见这个issueActivity继承AppCompatActivity的问题
然后你就编译该模块,会生成一个apk,在项目根目录新建一个目录叫plugin,将生产的apk拷到该目录
打开openatlasbundler项目中的BundleMakeBooter类,修改代码,将main函数前3句注释掉,加入下面三行代码。,目录指向的就是刚才新建的plugin目录。然后在该类上右键运行。
args=new String[2];
args[0]="C:\\Users\\kltz\\Desktop\\AtlasDemo\\plugin";
args[1]="C:\\Users\\kltz\\Desktop\\AtlasDemo\\plugin\\bundle-info.json";
最终会在plugin目录生成一个so和一个json
将该so拷到宿主程序的src/main/jniLibs/armeabi文件夹下,没有则新建。将json文件拷到src/main/assets目录下,没有则新建。
然后在宿主中添加测试代码,跳转到插件的Activity中去。如果成功跳转,说明你成功了一点点。
但是在运行前,你需要在宿主的清单中申明该Activity,必须申明哦
<activity android:name="com.lizhangqu.test.MainActivity" >
</activity>
Intent intent = new Intent();
intent.setClassName(MainActivity.this, "com.lizhangqu.test.MainActivity");
startActivity(intent);
我以相同方式加入二维码扫描,使用的是google的zxing。过程同test模块,最后调用
Intent intent=new Intent();
intent.setClassName(MainActivity.this,"com.lizhangqu.zxing.android.CaptureActivity");
startActivity(intent);
而且你还得在宿主的清单中加入权限,记住是宿主,在插件的清单中加入依然会报错。
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<!-- TODO replace above two with next line after Android 4.2 -->
<!-- <uses-feature android:name="android.hardware.camera.any"/> -->
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
<uses-feature android:name="android.hardware.screen.landscape" />
<uses-feature android:name="android.hardware.wifi" android:required="false" />
<!-- This excludes Google TV, which is unfortunately included by virtue of not requiring a camera -->
<uses-feature android:name="android.hardware.touchscreen" />
<!-- TODO make this not required again after android.hardware.camera.any is available -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
同时注意申明Activity
<activity android:name="com.lizhangqu.zxing.android.CaptureActivity" >
</activity>
成功打开扫描界面就可以了
总结为一句话就是基础的公共资源放在宿主中,插件中不要将这些东西依赖进去,只是以provided形式编译。
最后来看看使用了atlas之后,app的data目录会有什么变化。
最后,来看看淘宝Android客户端
简直完美,几乎是一样的,其实可以差不多确定淘宝的Atlas和OpenAtlas没什么区别了。
可能会有人不明白,插件apk是如何转化为so的,其实很简单,没有转化,只是修改了一个后缀而已,不信?不信你把so改成apk再安装一下试试,绝逼可以正常的跑!这也是个坑。告诉我们不要被表面迷惑
文章有点乱,不亲自试验过还是会看得迷迷糊糊的,提供源码下载。
http://download.csdn.net/detail/sbsujjbcy/8996357