CrossWalk - android 动态加载so库文件实践
2017-03-21 10:10
302 查看
之前看到
此前实现过一个在Android上的Markdown编辑器
但是界面以及
然后冒昧看了下
运行个demo,wrapper了一个http://sf.gg 发现体验真的是不错啊,webview性能到这个水平内心都宽慰了,但是为何安装速度那么慢呢?一看apk大小,足足有
好嘛,我把so文件先不放进apk中,让apk装好之后,放入
看日志入下:
DavlikDexClassLoader Unsatisfied Link library['/xxxx/xxx.apk', '/vendor/lib', '/system/lib']
一看这个路径,泪奔了,原来
再次启动,发现
于是我继续研究,开始看
我们知道
OK,知道怎么解决就方便了,首先,我们要把
我们仔细研究下它的源码,发现有几个标志位需要更改,具体代码如下:
只要把以上的类中的标志位更改掉,那么
简书Android客户端使用的编辑器,甚是喜欢,它的优雅以及高性能的特点让我爱不释手,很想自己也去做一个。
此前实现过一个在Android上的Markdown编辑器
但是界面以及
所见即所得的效果非常不好看,所以一直耿耿于怀。
然后冒昧看了下
简书的布局系统,看见了几个奇怪的类,包括类似
XWalkContentView,于是Google了下,就查到了
CrossWalk这个
hybrid框架了。第一眼并不觉得它有啥不一样,以为是一个
Cordova的轮子。后来细看,发现是自个儿编辑了整个
Chrominum,屌屌屌!
运行个demo,wrapper了一个http://sf.gg 发现体验真的是不错啊,webview性能到这个水平内心都宽慰了,但是为何安装速度那么慢呢?一看apk大小,足足有
40M+,感觉天都要塌了。
SegmentFault for Android客户端才
3.03M,我要是包上这玩意,估计就没多少人下了吧。。。然后又看看
简书,整个apk大小才8M,在启动编辑器的时候,提示需要下载编辑器,下载了一会,然后再打开。顿时就明白了,看来它的库是从外部载入的,记得以前看到过从外部加载
动态链接库想想很是简单,于是入坑了。
好嘛,我把so文件先不放进apk中,让apk装好之后,放入
/data/data/<app>/lib目录下,启动app,直接crash。
看日志入下:
DavlikDexClassLoader Unsatisfied Link library['/xxxx/xxx.apk', '/vendor/lib', '/system/lib']
一看这个路径,泪奔了,原来
library path只有三个路径下去检查,算了,我们不是有
System.load和
System.loadLibrary函数么,直接调用呗,于是我就先暂时把绝对路径给写了下来,直接调用
System.load函数。
再次启动,发现
CrossWalk报
Shared Library should use SharedXWalkView。但是使用
SharedXWalkView有许多的限制,比如需要安装一个
CrossWalk Runtime的apk,奇怪了,它怎么知道我是用
Shared Library的呢?而且简书也没有说要安装apk啊。
于是我继续研究,开始看
CrossWalk的源码,找到
ReflectionHelper这个类里面有一行代码
shouldUseLibrary(),它会去调用
System.loadLibrary()如果没有报异常,则返回
false,否则返回
true。
我们知道
System.loadLibrary这个函数,会去
java.library.path这个环境变量的路径下面寻找库,而
Android是不允许我们更改这个环境变量的值的,就导致
CrossWalk认为并没有加载它的
runtime而去开启
Shared模式。
OK,知道怎么解决就方便了,首先,我们要把
so文件放入到
/data/data/<app>/下的任意路径,因为我们的apk有这个权限在这里放东西,然后使用
System.load加载这个
so库,最后使用反射的方式欺骗
CrossWalk框架,告诉它我们的类库已经加载完毕。
我们仔细研究下它的源码,发现有几个标志位需要更改,具体代码如下:
System.load(libPath); try { LibraryLoader loader = LibraryLoader.get(1); Class c = Class.forName("org.xwalk.core.internal.XWalkViewDelegate"); Field field = c.getDeclaredField("sLibraryLoaded"); field.setAccessible(true); field.setBoolean(null, true); field.setAccessible(false); field = LibraryLoader.class.getDeclaredField("mLoaded"); field.setAccessible(true); field.setBoolean(loader, true); field.setAccessible(false); PathUtils.setPrivateDataDirectorySuffix("xwalkcore"); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (ProcessInitException e) { e.printStackTrace(); }
只要把以上的类中的标志位更改掉,那么
CrossWalk就认为库已经加载成功了。
相关文章推荐
- (4.1.27.11)Android动态加载so文件
- Android动态加载包含so文件的jar的自定义view控件
- Android动态加载so文件
- Android 开发中如何动态加载 so 库文件
- Android动态加载so文件
- Android JNI学习笔记——so文件动态加载
- CrossWalk - Android 动态加载so库文件
- Android动态加载so文件
- JNI动态加载so文件
- IDA Pro动态调试Android so文件
- android动态加载.so,实现动态库升级
- 携程Android App插件化和动态加载实践
- Android动态加载XML文件及控件来简单实现QQ好友印象的功能
- Cocos-X创建JS工程,编译Android .apk包,加载nanolink.so文件,创建一个实时对战游戏
- Android 打包so动态库文件到APK
- Android 打包so动态库文件到APK
- Android Eclipse JNI 调用 .so文件加载问题
- 加载动态链接库文件.so 失败出错—— No such file or directory (没有文件或目录)问题处理
- 携程Android App插件化和动态加载实践
- Java之—— JAVA Web项目中DLL/SO文件动态加载方法