Cordova插件开发(1)-Android插件开发详解

本篇文章讲述的是Android Cordova插件实践过程,具体实现包括以下五个方面:

1,实现原生自定义插件类;

2,配置Cordova插件;

3,注册Cordova插件;

4,定义Cordova插件调用方式;

5,调用Cordova插件;

本篇文章以安卓Toast插件实现过程为例。进入正题。

一,准备工作

需准备一个已添加Android平台的Cordova工程,插件实现基于此。这里就不写怎样创建Cordova工程以及添加Andoird平台了,这些都是最基本的。

二,具体实现

实践过程包含以下五个部分:实现自定义插件类、配置Cordova插件、注册Cordova插件、定义Cordova插件调用方式和调用Cordova插件。下面分别讲述:

1,实现自定义插件类ToastDemo.java

在 工程名/platforms/android/src目录下新建一个包,然后在该包下新建自定义插件类,并继承于CordovaPlugin(自定义插件都需要继承这个类),重写execute方法,在execute方法中实现自己想要的功能逻辑即可。以此demo为例,我是在 工程名/platforms/android/src目录下建的fxp.cordova.plugins包,然后新建ToastDemo.java类,所以此demo中插件类路径为:工程名/platforms/android/src/fxp/cordova/plugins/ToastDemo.java。不多解释,直接贴代码,代码中有注释:

package fxp.cordova.plugins;

import android.widget.Toast;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;

import java.util.Random;

/**
 * Created by fxp on 2017/4/14.
 */

public class ToastDemo extends CordovaPlugin {

    /**
     * @param action          The action to execute.
     * @param args            The exec() arguments, wrapped with some Cordova helpers.
     * @param callbackContext The callback context used when calling back into JavaScript.
     * @return
     * @throws JSONException
     */
    @Override
    public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {

        if ("toast".equals(action)) {
            String str = args.getString(0);
            Toast.makeText(cordova.getActivity(), str, Toast.LENGTH_LONG).show();
            return true;
        } else if ("toastWithCallback".equals(action)) {
            String str = args.getString(0);
            Toast.makeText(cordova.getActivity(), str, Toast.LENGTH_LONG).show();
            //为体现成功/失败两种回调,这里使用Random生成随机数,随机数为true时回调成功function,为false时回调失败function,
            Random random = new Random();
            if (random.nextBoolean()) {
                callbackContext.success("execute_callack_success");
            } else {
                callbackContext.error("execute_callack_error");
            }
            return true;
        }
        return super.execute(action, args, callbackContext);
    }

}

对于自定义插件类,额外补充以下两点:

  • 关于args值取用方式

a)  如果js传入的如果是对象数组,即[{“key”:”value”,”key”:”value”}],则如下取用:

JSONArray jsonarr = new JSONArray(args.getString(0)); 

JSONObject json = jsonarr.getJSONObject(0);

String str = json.get("key");


b)  如果js传入的如果是普通数组,即["a",10,true,…],则如下取用:

args.getString(0) 

args.getInt(1) 

args.getBoolean(2)

  • 关于线程

a)以上execute方法不是运行在WebView接口主线程,而是运行在WebCore线程;

b)如果想要运行在Activity的UI线程,以上execute方法可以参照下面写法:

    @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if ("toast".equals(action)) {
            final String str = args.getString(0);
            cordova.getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    //TODO

                    callbackContext.success(); // Thread-safe.                }
            });
            return true;
        }
        return super.execute(action, args, callbackContext);
    }

c)如果既不想运行在UI线程,又不想阻塞WebCore线程,以上execute方法可以参照下面写法:

    @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if ("toast".equals(action)) {
            final String str = args.getString(0);
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    //TODO
                    
                    callbackContext.success(); // Thread-safe.
                }
            });
            return true;
        }
        return false;
    }

2,在config.xml中配置Cordova插件

打开 工程名/platforms/android/res/xml/config.xml文件,在widget节点下添加如下feature:

    <!--ToastDemo插件-->
    <feature name="ToastDemo">
        <param name="android-package" value="fxp.cordova.plugins.ToastDemo" />
    </feature>

其中,feature的name值比较重要,可随意取,但后续都得统一;param的name值可以随意填写,value值为插件实现类的路径,即【包名】.【类名】。


3,在cordova_plugins.js中注册Cordova插件

打开 工程名/platforms/android/assets/www/cordova_plugins.js文件,在module.exports数组中添加自定义插件信息。此demo中是在module.exports数组中添加以下元素:

{
        "file": "plugins/fxp-cordova-plugins/www/ToastDemo.js",//js文件路径
        "id": "fxp-cordova-plugins.ToastDemo",//插件moduleid。对应cordova.define的第一个参数
        "clobbers": [
            "fxp"//js中调用时使用的对象名
        ]
    }

一个plugin可以有多个module,类似于Android Studio中project和module的概念,这里的id是插件当前module的id,命名规则为【插件id】.【feature的name值】。插件id应使用"pluginId"为key值。此示例中,"pluginId":"fxp-cordova-plugins"。

4,定义Cordova插件调用方式

在 工程名/platforms/android/assets/www/plugins路径下创建自己的文件夹,并在自己的文件夹下创建www目录,然后在此www目录下创建定义插件使用方式的js文件(可以把所有定义插件使用方式的js文件都放在这个www文件夹下)。以此demo为例,我所创建的TestDemo.js文件路径为:工程名/platforms/android/assets/www/plugins/fxp-cordova-plugins/www/TestDemo.js。插件通常有两种使用形式:有回调方法和无回调方法。TestDemo.js文件内容如下:

/**
* cordova.define 的第一个参数就是cordova_plugins.js里面定义的id
* exec方法参数说明:
* 参数1:成功回调function
* 参数2:失败回调function
* 参数3:feature name,与config.xml中注册的一致
* 参数4:调用java类时的action
* 参数5:要传递的参数,json数组格式
* 下面提供三种实现方式,三种实现方式均可行
*/
cordova.define("fxp-cordova-plugins.ToastDemo",
    function(require, exports, module) {

        /*
         * 实现方式一
        */
        var exec = require("cordova/exec");
        module.exports = {
            toast: function(content){
                exec(null,null,"ToastDemo","toast",[content]);
            },
            toastWithCallback: function (content, successCallback, errorCallback) {
                cordova.exec(successCallback, errorCallback, "ToastDemo", "toastWithCallback", [content]);
            }
        }

        /*
         * 实现方式二
        */
/*        var exec = require('cordova/exec');
        var FXP = function(){};
        FXP.prototype.toast=function(content) {
            exec(null, null, "ToastDemo", "toast", [content]);
        };
        FXP.prototype.toastWithCallback=function(content,success, error) {
            exec(success, error, "ToastDemo", "toastWithCallback", [content]);
        };
        var fxp = new FXP();
        module.exports = fxp;*/

        /*
         * 实现方式三
        */
/*        var exec = require('cordova/exec');
        exports.toast = function(content) {
            exec(null, null, "ToastDemo", "toast", [content]);
        };
        exports.toastWithCallback=function(content, successCallback, errorCallback){
            exec(successCallback,errorCallback,"ToastDemo","toastWithCallback",[content]);
        };*/
});


5,调用Cordova插件

完成以上4步后一切均已就绪,可以直接调用了。调用方式为:

[clobbers].[action]
以此demo为例:

        fxp.toast("toast");

        fxp.toastWithCallback("toastWithCallback",function(success){
            alert(success);
        },function(error){
            alert(error);
        });

至此,games over!

三,写在后面

1,本文实现的是简单的toast插件,意在讲述插件的实践过程;

2,因此demo实践都是在 工程名/platforms/android目录下,所以调试时不要执行cordova build 或  cordova run 命令(执行此命令后,工程名/platforms/android/assets/www将被替换导致前面所加代码丢失);

3,后面有空会再写一篇博文讲述自定义插件安装方式;

4,不足之处,欢迎批评指正;


/***************************************2018.6.28补充 start ***************************************/

1,时隔一年半再回头看这篇博文,竟发现有的东西讲得不是很准确,已修正。请见谅。

2,以上自定义插件实现方式是根据Cordova官方文档标准流程。但仔细看了cordova源码之后,发现实际上有更加简单的实现方式:

以上流程中的第3、4步均可省略,不用在cordova_plugins.js中注册,也不用写TestDemo.js提供调用方法,直接如下即可调起:

Cordova.exec(successCallback,errorCallback,"ToastDemo","toast",[content]);


/***************************************2018.6.28补充 end ***************************************/










  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值