当前位置:编程学习 > JAVA >>

Android开发中java与javascript交互:PhoneGap插件vs addJavascriptInterface

1.        前言

在《用PhoneGap+jQueryMobile开发Android应用实例》中,我们讲到PhoneGap(以下称Cordova)开发环境的搭建,以及如何整合出一个基本的Android应用框架(并给出了范例代码)。于是乎,我们便开始日夜兼程,披星戴月的炮制我们的第一个手机应用了。

但实际上,除了常见的API调用规范(有且仅有自查手册一途)引起的问题之外,我们仍然会遇到其他形形色色的各种问题。那么在这篇文章中,我们谈谈java与js之间的交互问题(哦,目前仅关注Android,所以只能谈java了)。当然,二者之间的交互目的,原因会有种种不同,但应该还是以发挥语言各自的优势,提供接口给对方调用的意图居多。

我们知道,在Android平台下,Cordova是通过内置WebKit内核的方式来实现界面容器的(事实上,在其他平台也是如此)。我们也同样知道,Cordova是一个桥接框架,其目的就是为原生API和js建立桥接,互通有无的。为了便于我们扩展自己的应用,Cordova还提供了插件(PlugIn)机制(当然,我们还可以直接修改Cordova开源代码)。只要遵循一定的规则(恩恩,事实上这个规则很简单),就可以扩展出丰富的功能特效来。

 

2.        Cordova插件与 WebView.addJavascriptInterface

恩恩,本文的主题是java与js的交互(差点跑了)。刚提到的,Cordova有插件机制,可以通过插件的形式,实现java与js交互,为什么还要提到addJavascriptInterface?

Cordova插件确实可以实现二者的交互,而且是异步的,非常方便。但基于一些特殊的原因,例如:一个回调需要被多次调用(啊哈,或许是我太菜?使用PlugIn注册的回调都只能被调用一次)。又或者不想写插件,想直接点。

总之,插件也并不是时时处处都符合我们的需求(我们的欲望无穷大啊),总是要找办法解决,寻点不同的路出来(个人不是特别认同Cordova的Hack方式,遑论其插件;而且Cordova目前的状态有点怪异,版本更新是很快,但文档更新不同步)。要真正成熟,还是有一段路要走的。

addJavascriptInterface则是WebKit的原生API,属于WebView对象的公共方法,用于暴露一个java对象给js,使得js可以直接调用java方法。当然,我们要实现java与js的双向交互,还需要另一个方法loadUrl(同属于WebView对象,Cordova也是采用的这个方法调用js的)的配合。

当然,这两种方式互有优劣(只有实践时,才会明白啊)。Cordova插件的不足刚才已经提过;而addJavascriptInterface也有些问题,一是Android平台封装WebKit内核时,不同的版本中有些许不一致;其次,直接使用loadUrl加载js实在是让人头疼。

其实应该有更好的方法,比如扩展js引擎(我更喜欢这种方式),但这种方式相对而言,涉及的内容繁杂,暂时不纳入这次的话题。

 

3.        Cordova插件的实现

Cordova插件分为两个部分(额,Cordova本身也是分为两个部分的,别扭不?),一部分由java实现,另一部分由js实现。

1)        java部分

Cordova插件的java部分很简单,继承Cordova.Plugin,实现execute方法就可以了:

public classNotificationClient extends Plugin {

         private static final String TAG ="NotificationClient";

         private String callbackId ="";

         public PluginResult execute(Stringaction, JSONArray args, String callbackId) {

                   PluginResult.Status status =PluginResult.Status.OK;

                   if(action.equals("register")){

                            try {

                                     register(args.getString(0),args.getString(1));

                            } catch(JSONException e) {

                                     status =PluginResult.Status.JSON_EXCEPTION;

                            }

                   } elseif(action.equals("watch")) {

                            this.callbackId =callbackId;

                            PluginResult r = newPluginResult(PluginResult.Status.NO_RESULT);

                            r.setKeepCallback(true);

                            return r;

                   } else {

                            status =PluginResult.Status.INVALID_ACTION;

                   }

                   return newPluginResult(status);

         }

         public Object onMessage(String id,Object data) {

                   Log.d(TAG,"onMessage(" + id + ").");

                   if(id.equals("onClientNotification")){

                            if(!callbackId.equals("")){

                                     this.success("true",callbackId);

                            }

                   }

                   return data;

         }

         private void register(String username,String phone) {

                   Log.d(TAG,"register(" + username + ", " + phone + ").");

         }

}

嗯,就这样,作为一个Cordova插件java部分的范例,他已经完成了使命(原谅我为了节省篇幅,删掉

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,