segmentfault.com/a/1190000002919135 

之前看到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//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//下的任意路径,因为我们的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就认为库已经加载成功了。

更多相关文章

  1. PhoneGap对比html5写android应用程序【android进化三十八】
  2. Android基础入门教程——7.5.1 WebView(网页视图)基本用法
  3. Android类加载之PathClassLoader和DexClassLoader
  4. SQLite的使用
  5. android Uri使用
  6. Android系统启动流程分析
  7. Android(安卓)热更新是如何实现的?
  8. 在android中举例说明用Environment、StatFs以及DecimalFormat来
  9. Android(安卓)驱动库的动态加载

随机推荐

  1. Android下拉列表
  2. Android通过PagerSnapHelper改造Recycler
  3. Android添加垂直滚动ScrollView
  4. Android(安卓)自定义控件打造史上最简单
  5. Android(安卓)中文 API (24) ―― MultiAut
  6. Android之网络请求7————OkHttp源码4:
  7. Cordova 3.x 基础(13) -- 为Android(安卓)A
  8. Android实现CBC加解密
  9. dx 工具的使用
  10. 获取Android设备电池电量状态