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 代码调用原生代码的方法中,我们需要传入运行成功的回调函数和运行失败的回调函数,原生代码的运行结果就是通过这两个函数来返回的。具体代码如下:

    // JS 调用 Java 代码。
    cordova.exec(successCallback, errorCallback, 'JavaClassName', 'functionName', args);
    
    // 在 Java 代码中,返回运行结果。
    void functionName(JSONArray data, CallbackContext callback) {
        if() {  // 运行成功
          callback.success('运行成功的返回结果');  
        } else {
          callback.error('运行失败的返回结果');
        }
    }
    
     // 回调函数
     var successCallback = function(result) {
       // result 就是 '运行成功的返回结果';
     }; 
    

复杂的返回结果,推荐使用 JSONObject 来组织返回对象。

  • 在 Android 端的开发中,如果想在插件的 Java 代码中来和 JavaScript 代码交互,由于 Android 的 WebView 是运行在主线程中,所以在运行过程中可能会产生阻塞问题。通常会有以下两种情况:

    • 如果当前你插件中的原生代码正在和 UI 界面交互,或者你就希望某个方法运行在 UI 线程中,可以用下面的代码:

      cordova.getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
          // 你要执行的代码
        }
      });
      
    • 如果当前你的插件代码没有和 UI 进行交互,或者有耗时的操作希望能运行在独立线程中,可以使用下面的代码:

      cordova.getThreadPool().execute(new Runnable() {
        @Override
        public void run() {
          // 你要执行的代码
        }
      });
      
  • 在 Java 代码中如果想调用 js 方法,并且想要传递一个 Json 格式的数据到 js 的方法,当 Json 格式数据中包含引号时,如果不注意的话,很有可能会导致数据传递错误。具体解决方法如下:

      // 注意 %s 不要再加引号。
      String format = "window.plugins.yourPlugin.function(%s)";
      final String js = String.format(format, jsonData.toString());
      cordova.getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
          webView.loadUrl("javascript:" + js);
        }
      });
      // 然后在 js 端的解析调用:
      jsonStr = JSON.stringify(jsonStr);
      var obj = JSON.parse(jsonStr);
  • Android 中的 CallbackContext.success() 方法默认只会执行一次回调,如果想通过一个 CallbackContext 重复发送回调结果就会失败。
    这时我们可以自定义 PluginResult 对象,并调用 setKeepCallback(true); 方法保持 CallbackContext:
    PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, value);
    pluginResult.setKeepCallback(true);
    mCallback.sendPluginResult(pluginResult);
    
  • 因为 Cordova 的开源性质和产品定位,使得每个人都可以开发自己的 Cordova 插件,这也就导致了目前的 Cordova 插件质量参差不齐。
    因此在选用 Cordova 插件时一定要擦亮眼睛 = =。在这里也讲一下我用过的一些还不错的插件:
    • 首先,和硬件交互相关的场景,最好使用 Cordova 的官方插件,这些插件都是经过了实践检验的,基本是不会有什么太大的问题的,具体的插件列表可以去 Apache 的 Github 主页搜索 cordova 关键字查看,也可以在这里查看 Cordova 发布日志。
    • 推送功能由于具体国情,推荐选用国内自己的推送服务,而目前国内只有极光推送官方推出了 Cordova 插件,还是蛮好用的,有 issue 解决的也很快,推荐使用。项目地址:https://github.com/jpush/jpush-phonegap-plugin
    • Github 上有位国外开发者开发了一些 Cordova 插件,虽然没有一一试用,但是看了下感觉还是写得不错,推荐大家可以关注一下,Github 地址:https://github.com/katzer

上面只是列出了一些我自己开发过程中遇到的当时比较头疼的问题和一些体会,欢迎大家留言交流,我也会不定期更新一些新的问题。^ ^

你可能感兴趣的:(Cordova 开发里踩过的那些坑)