注册

Android与JS相互通信

Android与JS相互通信">">

Android调用js的方法实现是引入一个webview用webview打开一个页面调取的JS函数。

private void InitWebView() {
mWebView = (WebView) findViewById(R.id.webview);

WebSettings webSettings = mWebView.getSettings();

// 设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

//把js弹窗转化成安卓弹窗
SetJavaScriptAlertEnable();

// 先载入html代码
// 格式规定为:file:///android_asset/文件名.html
// 只需要将第一种方法的loadUrl()换成下面该方法即可
// Android版本变量
//mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS类对象映射到js的test对象
mWebView.loadUrl("file:///android_asset/javascript.html");
//SetWebChromeClient()//处理JS调用Android函数的方法在第二部分解释

}
复制代码

首先先初始化webview

第二步对webview基本初始化

第三部设置JS交互权限

其余有明确注释

loadurl是加载html网页端的

我们以button点击开始执行js事件为例

首先app/src/main下创建assets文件

下面是javascript.html文件我们在引入文件时需要将文件放到所在的Android项目的/project_home/app/src/main/assets/javascript.html 下就可以使用了。

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>Carson_Ho</title>
<h1 id="ip">
你好这里已经调用过文件了
</h1>
<button onclick="callJS()">调用弹窗</button>
<button type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
<button type="button" id="button2" onclick="clickprompt()">点击调用Androidtest代码</button>
<script>
function callJS() {
alert("Android调用了JS的callJS方法");
}

function change() {
document.getElementById('ip').innerText = "真的难啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊a";
}
function clickprompt(){
var result=prompt("js://demo?arg1=111&arg2=222");
alert("demo " + result);
}
function callAndroid(){
// 由于对象映射,所以调用test对象等于调用Android映射的对象
test.hello("js调用了android中的hello方法");
}

</script>

// JS代码
<script src="./1/roslib.min.js"></script>
<script src="./1/RoboX.js"></script>

</head>

</html>
复制代码

将JS弹窗改为Android弹窗方法SetJavaScriptAlertEnable();

private void SetJavaScriptAlertEnable() {
// 由于设置了弹窗检验调用结果,所以需要支持js对话框
// webview只是载体,内容的渲染需要使用webviewChromClient类去实现
// 通过设置WebChromeClient对象处理JavaScript的对话框
//设置响应js 的Alert()函数
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
//设置弹窗
AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this);
b.setTitle("Alert");
b.setMessage(message);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
b.setCancelable(true);
b.create().show();
return true;
}
});
}
复制代码

初始化界面用button测试程序是否能通信。

private void InitView() {

button = (Button) findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过Handler发送消息
mWebView.post(new Runnable() {
@Override
public void run() {

// 注意调用的JS方法名要对应上
// 调用javascript的callJS()方法
final int version = Build.VERSION.SDK_INT;//获取系统版本
//我们需要判断当前系统版本。为了尽可能减少错误我们使用了两种方式来实现调用JS方法。
if (version < 18) {
mWebView.loadUrl("javascript:callJS()");
} else {

// Toast.makeText(getApplicationContext(), "单击完成", Toast.LENGTH_SHORT).show();


//Toast.makeText(getApplicationContext(), ans.toString(), Toast.LENGTH_SHORT).show();
mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//此处为 js 返回的结果
}
});
mWebView.evaluateJavascript("javascript:change()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//此处为 js 返回的结果
}
});
}
}
});

}
});
}
复制代码

下面是JS同Android的通信,JS调用Android的函数方法。

将上边webview初始化中取消注释SetWebChromeClient()同时取消注mWebView.addJavascriptInterface(new AndroidtoJs(), "test");重新创建一个类继承于Object同时创建的test对象在js中同样如此像HTML文件中的

function callAndroid(){
// 由于对象映射,所以调用test对象等于调用Android映射的对象
test.hello("js调用了android中的hello方法");
}
复制代码

下面是创建的类AndroidtoJS

import android.webkit.JavascriptInterface;

public class AndroidtoJs extends Object {
@JavascriptInterface
public void hello(String msg) {
System.out.println("JS调用了Android的hello方法woc");
}
}

复制代码

SetWebChromeClient()是处理JS和Android之间通信的在下边有详细解释

private void SetWebChromeClient() {
mWebView.setWebChromeClient(new WebChromeClient() {
// 拦截输入框(原理同方式2)
// 参数message:代表promt()的内容(不是url)
// 参数result:代表输入框的返回值
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
// 根据协议的参数,判断是否是所需要的url(原理同方式2)
// 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
//假定传入进来的 url = "js://demo?arg1=111&arg2=222"(同时也是约定好的需要拦截的)

Uri uri = Uri.parse(message);
// 如果url的协议 = 预先约定的 js 协议
// 就解析往下解析参数
if (uri.getScheme().equals("js")) {

// 如果 authority = 预先约定协议里的 webview,即代表都符合约定的协议
// 所以拦截url,下面JS开始调用Android需要的方法
if (uri.getAuthority().equals("demo")) {

//
// 执行JS所需要调用的逻辑
System.out.println("js调用了Android的方法");
// 可以在协议上带有参数并传递到Android上
HashMap<String, String> params = new HashMap<>();
Set<String> collection = uri.getQueryParameterNames();

//参数result:代表消息框的返回值(输入值)
result.confirm("js调用了Android的方法成功啦");
}
return true;
}
return super.onJsPrompt(view, url, message, defaultValue, result);
}

// 通过alert()和confirm()拦截的原理相同,此处不作过多讲述
// 拦截JS的警告框
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}

//拦截JS的确认框
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
}
);
}

复制代码

我们不是采用直接调用的方法而是采用拦截的方法

第一次接触Android项目有的地方写的可能有问题有的地方说的也可不能不准确,大家下方积极留言,第一次写博客排版也没搞好大家见谅吧哈哈哈哈。

0 个评论

要回复文章请先登录注册