Cordova下android与javascript的交互

Igor Android评论10,031字数 3685阅读12分17秒阅读模式

最近做了一个功能,公司是用html写的上层,需要调用android自带的语音合成和识别,原以为是直接与html交互,结果没想到上层是用cordova的框架写的,研究一天把cordova与android的交互实现了,现在记录一下实现流程
由于是第一次用到Cordova,所以把它的搭建android项目和实现流程一并写上。

一、用Cordova搭建一个android工程。
下载nodejs,并配置环境变量(默认)
打开https://nodejs.org/en/,下载nodejs并安装,安装好默认是配置好环境变量的(我下载的v4.5.0LTS这个版本),输入npm如图即装好

安装Cordova      npm install -g cordova

创建一个cordova工程     cordova create (工程名) (包名)

将这个工程配置到Android      在这个工程目录下(cd ProjectName) cordova platform add android

AndroidStudio 导入这个项目

ps:我的androidStudio版本是2.1.2,第一次导入特别慢,我导入了20分钟,导入了之后一直卡在gradle加载界面。实际上并不需要,先导入项目,然后打开任务管理器关闭studio之后再重新导入项目,几乎瞬间就好了。

二、js调用android方法
创建一个java类,继承CordovaPlugin。本例是js调用native中的speak方法
public class SpeechOFFSynthesize extends CordovaPlugin{
public void speak(String content){
Log.e("SpeechOFFSynthesize",content);
}

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if("speak".equals(action)){
//speechSynthesize
String content = args.getString(0);
speak(content);
callbackContext.success("finish");//如果不调用success回调,则js中successCallback不会执行
return true;
}
return false;
}
}

配置插件,在res/xml/config.xml下,value为包名+类名

js调用
html比较简单,就一个button,代码就不贴了。

<script>
$("#button").click(function(){
cordova.exec(success, fail, "SpeechOFFSynthesize", "speak", ["haha"]);
});
var success = function(message){
alert("success = "+message);
};
var fail = function(message){
alert("fail = "+message);
};
</script>

最后就是调用speak,打出日志了

三、android调用js方法
js:

<script>
<!-- android调用js方法 -->
function showAlert(content){
alert(content);
}
</script>

android:

public class MainActivity extends CordovaActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
runOnUiThread(new Runnable() {
@Override
public void run() {
//不能在子线程中执行webview的方法
loadUrl("javascript:showAlert(\"你好\")");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}

由于需要等html完全加载完JS之后,Android的调用才能有效果,否则会没反应,所以我让它在子线程中等待了10秒然后在主线程中去调用js的方法。

四、CordOva加载外网
所有东西弄完了之后,导入到AndroidStudio里面,web文件是放在assets里面,能正常运行,可是放在外网里,却无法加载。
研究了一下发型是因为在CordovaLibs工程里,CordovaBridge文件中,有这样一段。

else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
// Protect against random iframes being able to talk through the bridge.
// Trust only pages which the app would have been allowed to navigate to anyway.
if (pluginManager.shouldAllowBridgeAccess(origin)) {
// Enable the bridge
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
jsMessageQueue.setBridgeMode(bridgeMode);
// Tell JS the bridge secret.
int secret = generateBridgeSecret();
return ""+secret;
} else {
Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
}
return "";
}

这里它限制了外网的加载,所以允许所有加载即可,代码如下:

else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
// Protect against random iframes being able to talk through the bridge.
// Trust only pages which the app would have been allowed to navigate to anyway.
// if (pluginManager.shouldAllowBridgeAccess(origin)) {
// Enable the bridge
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
jsMessageQueue.setBridgeMode(bridgeMode);
// Tell JS the bridge secret.
int secret = generateBridgeSecret();
return ""+secret;
// } else {
// Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
// }
// return "";

由于cordova的加载url是封装在CordovaLib下的ConfigXmlParser,为了防止修改url出现其他问题,所以我是用 EventBus,将url传过去的。

private void setStartUrl(String src) {
Pattern schemeRegex = Pattern.compile("^[a-z-]+://");
Matcher matcher = schemeRegex.matcher(src);
if (matcher.find()) {
launchUrl = src;
} else {
if (src.charAt(0) == '/') {
src = src.substring(1);
}
launchUrl= EventBus.getDefault().getStickyEvent(String.class);
}

---------------------
作者:Hoyn
来源:CSDN
原文:https://blog.csdn.net/adzcsx2/article/details/52597088
版权声明:本文为博主原创文章,转载请附上博文链接!

来源: Cordova下android与javascript的交互 - adzcsx2的博客 - CSDN博客

文章末尾固定信息

weinxin
我的微信
我的微信
一个码农、工程狮、集能量和智慧于一身的、DIY高手、小伙伴er很多的、80后奶爸。
 
Igor
  • 本文由 Igor 发表于 2019-02-2418:41:06
Vue使用JsBridge与APP交互 Web服务器

Vue使用JsBridge与APP交互

现在在做的项目是 hybrid 开发,H5 页面会嵌入到 IOS 客户端 app 中,于是就涉及到了 H5 与 IOS 交互的问题。在这里记录一下项目中用到的交互方式,重点介绍 WebViewJava...
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定

拖动滑块以完成验证