Cordova踩坑历程
随着前端技术的发展,现在国内外都涌现出了许多移动应用混合开发框架。比如国外的 PhoneGap / Cordova, Ionic, Meteor, 微软收购的 Xamarin 和 国内的 MUI, APICloud, WeX5, 以及最近阿里刚发布的 Weex 等等。
当然这些框架各有特点,但是目前比较成熟的解决方案个人认为还是 Ionic + PhoneGap / Cordova。
因为目前 Cordova 是在 Apache 旗下,技术实力可以得到保证,并且已经发展多年,有很多的框架都兼容 Cordova,例如上面提到的 Ionic , Meteor 和 WeX5 都可以使用 Cordova 插件。在开发工具方面,微软已经在 Visual Studio 中增加了对 Cordova 开发的支持,JetBrains 的 WebStorm 也默认可以开发 Cordova 应用,这也是看好 Cordova 前景的一种表现吧。
我也尝试了一下 Cordova 开发,其中当然免不了的要踩坑,所以在这里列出一些当时比较头疼的问题和心得来供大家参考:
在使用第三方插件时,如果自行扩展了插件,在用命令行工具编译时要使用 cordova compile 而不要用 cordova build 命令,因为 cordova build 命令其实是 cordova prepare + cordova compile,而 cordova prepare 命令做的就是根据插件中的 config.xml 将插件文件复制到项目中,这样就会把你修改了的插件文件替换掉,所以如果只是想编译项目,就只使用 cordova compile 命令吧。
插件中 Java 端返回运行结果给 JavaScript 代码:
在用 JS 代码调用原生代码的方法中,我们需要传入运行成功的回调函数和运行失败的回调函数,原生代码的运行结果就是通过这两个函数来返回的。具体代码如下:
1 | // JS 调用 Java 代码。 |
复杂的返回结果,推荐使用 JSONObject 来组织返回对象。
在 Android 端的开发中,如果想在插件的 Java 代码中来和 JavaScript 代码交互,由于 Android 的 WebView 是运行在主线程中,所以在运行过程中可能会产生阻塞问题。通常会有以下两种情况:
如果当前你插件中的原生代码正在和 UI 界面交互,或者你就希望某个方法运行在 UI 线程中,可以用下面的代码:
1 | cordova.getActivity().runOnUiThread(new Runnable() { |
如果当前你的插件代码没有和 UI 进行交互,或者有耗时的操作希望能运行在独立线程中,可以使用下面的代码:
1 | cordova.getThreadPool().execute(new Runnable() { |
在 Java 代码中如果想调用 js 方法,并且想要传递一个 Json 格式的数据到 js 的方法,当 Json 格式数据中包含引号时,如果不注意的话,很有可能会导致数据传递错误。具体解决方法如下:
1 | // 注意 %s 不要再加引号。 |
1 | // 然后在 js 端的解析调用: |
Android 中的 CallbackContext.success() 方法默认只会执行一次回调,如果想通过一个 CallbackContext 重复发送回调结果就会失败。
这时我们可以自定义 PluginResult 对象,并调用 setKeepCallback(true); 方法保持 CallbackContext:
1 | PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, value); |
因为 Cordova 的开源性质和产品定位,使得每个人都可以开发自己的 Cordova 插件,这也就导致了目前的 Cordova 插件质量参差不齐。
因此在选用 Cordova 插件时一定要擦亮眼睛 = =。在这里也讲一下我用过的一些还不错的插件:
首先,和硬件交互相关的场景,最好使用 Cordova 的官方插件,这些插件都是经过了实践检验的,基本是不会有什么太大的问题的,具体的插件列表可以去 Apache 的 Github 主页搜索 cordova 关键字查看,也可以在这里查看 Cordova 发布日志。
推送功能由于具体国情,推荐选用国内自己的推送服务,而目前国内只有极光推送官方推出了 Cordova 插件,还是蛮好用的,有 issue 解决的也很快,推荐使用。项目地址:https://github.com/jpush/jpush-phonegap-plugin