PhoneGap 08 Android 插件介绍

本节描述了在Android平台上面使用本地代码怎么实现插件。在读这一部分前,需要先阅读插件体系及其提供的javascript通用接口,这一部分同样以echo作为例子。对于其他的例子,可以查看CordovaPlugin.java.

Android插件是基于Cordova-Android,它包含通过钩子与其连接的Android WebView。插件是通过在config.xml里面的一个类来表示的。一个插件至少包含一个继承自CordovaPlugin并重写了它的execute()方法的类。最好的处理办法是插件也处理pause和resume事件,这些事件在插件之间传输比较多。需要长时间运行的请求、后台运行的服务,比如媒体播放、监听程序或者内部状态需要实现onReset()接口,它是在webview执行到新页面或者load javascript文件并刷新的时候执行。

插件映射

插件的javascript接口像下面这样使用 cordova.exec方法

exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);

它封装一个从WebView到Android本地调用的请求,调用service类的action方法,通过args传递需要的参数。

不管你是使用java文件或者jar文件作为插件,插件必须在config.xml文件中标明。

<feature name="<service_name>">
        	<param name="android-package" value="<full_name_including_namespace>" />
    	</feature>

service_name对应javascript exec调用的名称,value属性表示类的全名,否则,插件可以编译但是永远不会被调用。

写一个java插件

javascript调用可以触发一个插件请求一个本地代码,以config.xml映射的方式与插件进行通信。但是android插件到底是怎么样的呢?javascript的exec方法传递给插件的execute方法。execute大多是像下面这样的:

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("beep".equals(action)) {
            this.beep(args.getLong(0));
            callbackContext.success();
            return true;
        }
        return false;  // Returning false results in a "MethodNotFound" error.
    }

javascript的exec函数的action参数对应于私有类的方法。

当检测到异常并返回错误的时候,尽快安全地处理从java中返回给javascript的错误就是相当重要的。

线程

插件的javascript代码不能运行在webview接口的主线程中。而是跟execute() 方法一样运行在WebCore线程中,如果这一过程需要跟UI交互,你需要像下面这样:

    @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if ("beep".equals(action)) {
            final long duration = args.getLong(0);
            cordova.getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    ...
                    callbackContext.success(); // Thread-safe.
                }
            });
            return true;
        }
        return false;
    }

如果你既不需要在主线程中运行,也不想阻塞WebCore线程,你可以像下面这样做:

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

Echo 插件例子

为了配合在应用程序插件里面描述的javascript echo feature 接口,使用plugin.xml向本地平台的config.xml里面注入一个 feature:

    <platform name="android">
        <config-file target="config.xml" parent="/*">
            <feature name="Echo">
                <param name="android-package" value="org.apache.cordova.plugin.Echo"/>
            </feature>
        </config-file>
    </platform>
然后增加下面的代码到src/org/apache/cordova/plugin/Echo.java文件里面:
    package org.apache.cordova.plugin;

    import org.apache.cordova.CordovaPlugin;
    import org.apache.cordova.CallbackContext;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    /**
     * This class echoes a string called from JavaScript.
     */
    public class Echo extends CordovaPlugin {

        @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
            if (action.equals("echo")) {
                String message = args.getString(0);
                this.echo(message, callbackContext);
                return true;
            }
            return false;
        }

        private void echo(String message, CallbackContext callbackContext) {
            if (message != null && message.length() > 0) {
                callbackContext.success(message);
            } else {
                callbackContext.error("Expected one non-empty string argument.");
            }
        }
    }

必须导入的包首先是CordovaPlugin,它的execute方法重写了从exec哪里接收的信息的处理方式。execute方法首先需要测试action的值,必须要能够找到想对应的方法才行,在这个例子中仅有一个echo方法,所以可以进行直接的判断,不然一般情况都需要分支结构来进行判断。如果找不到相应的函数,则会返回false,并且在javascript调用端会引起一个INVALID_ACTION错误。

接下来,通过object的getString()方法得到传递给函数的第一个参数,接着讲该参数传递给私有的echo函数,它检测参数是否为null或者空,如果是,通过callbackContext.error()调用javascript的错误处理函数。如果各种情况都通过之后,通过callbackContext.success()将原始的消息作为参数传递给javascript调用时的successFunction函数。

Android集成

Android的Intent特征允许进行间相互通信。插件必须能够访问到CordovaInterface对象,该对象可以访问到运行程序的Android主Activity。这是一个运行Android Intent必须的上下文。CordovaInterface允许插件去开启一个Activity并且从中获取结构,或者为Intent返回到应用程序的时候设置一个回调的插件。

从Cordova 2.0开始,插件不再能够直接访问到Context了,并且惰性ctx成员变量也被标记为过时。现在所有的ctx方法都存在在Context对象中,可以通过getContext()或者getActivity()得到

调试Android插件

Eclipse可以调试插件,将插件作为java源文件包含在项目中。但是仅仅只有最新的ADT工具才支持。


原文链接:Android Plugins

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值