您的位置:首页 > 移动开发 > Android开发

Android学习之WebView和JS的交互

2017-11-08 17:54 1091 查看
最近做一个项目的时候,需要写一个简单的富文本编译器

本来是打算用安卓里面的Span来写,可是太复杂了,然后看到JS中的富文本编译器,实现简单,代码逻辑清楚,所以记录记录

现在很多App里面都内置了Web网页,涉及Android客户端和Web网页的交互

(感觉android快失业了~)

其实android和JS相互调用时通过WebView,其实就是:

android调JS代码

JS调android代码

android调用JS代码的方法:

1,通过webView的loadUrl()

2,通过webView的evaluateJavaScript()

JS调用android代码的方法:

1,通过webView的addJavaScriptInteface()进行对象的映射

2,通过WebCilent的shouldOverrideLoading()方法回调拦截url

3,通过WebChromeClient的onJsAlert(),onJsComfirm(),onJsPrompt()方法回调JS对话框alert(),confirm(),prompt()消息

具体来看:

Android调用Js方法

首先我们需要在mian下的assets包里面创建我们的html文件

将需要调用的JS代码以.html格式放到src/main/assets文件夹里

这是一个本地的文件

<!DOCTYPE html>
<html>

<head>

<meta charset = "utf-8"/>
//记得我在上篇WebView基础中介绍过WebView自适应屏幕 mSettings.setUseWideViewPort(true)这个东西
//就是使用的这个
<meta name="viewport" content="width=device-width,
initial-scale=1.0, minimum-scale=1.0,
maximum-scale=1.0, user-scalable=no">

<style>
img{
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px;
width: 80px;
height: 80px;

}

div{
border: 1px solid #00868B;
fontSize: 16sp;
padding:10px 5px;
fontFamily :Arial;

}
</style>

<script>

function Bold() {

var aa = document.execCommand("Bold", "false", null);

}

function  AddImage(param){

var img = document.createElement("img");
img.src = param;

document.getElementById("editText").appendChild(img);

}

function  deleteLine(){

document.execCommand("StrikeThrough",false,null);
}

function size(param){

document.execCommand("FontSize",false,param);

}

function AddTitle(){

document.execCommand("FontSize",false,5);

}

function setFontColor(param){

document.execCommand("ForeColor",false,param);

}

function Init(){
document.getElementById("editText").style.fontSize = "4";
document.getElementById("editText").style.fontColor = "#fff";
document.getElementById("editText").style.fontFamily = "Arial";
}

</script>

</head>

<body>

<div contenteditable = "true"  width= "400px"
id="editText"
>

请输入... ....
</div>

</body>

</html>


然后在Android里面通过WebView去调用JS代码

mSettings = mWebView.getSettings();
//让webView自适应屏幕
mSettings.setUseWideViewPort(true);
mSettings.setLoadWithOverviewMode(true);
mSettings.setLoadsImagesAutomatically(true);
//不支持缩放
mSettings.setSupportZoom(false);
//设置与JS交互的权限
mSettings.setJavaScriptEnabled(true);
//加载本地JS代码
mWebView.loadUrl("file:///android_asset/TextEdit.html");


这里我使用的是loadUrl去调用JS代码:

假如我需要将字体变成粗体:

我可以这样:

mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:Bold()");
}
});


我想改变字体的大小:

mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:size(4)");
}
});


我这里只是测试

我们来看看效果:



注意,在JS中添加图片必须是真实存在的图片,否则无法添加

这个是待完善版。。。

假如我们需要将JS中代码的结果返回回来:

我们需要用到evaluateJavascript()

它的优点:它比第一种方法效率更高,使用更简洁

该方法的执行不会 使页面刷新,而第一种方法(loadurl())的执行会

Android4.4后才能使用

我重新创建一个html文件:

<script>

function callJS(){
var result = prompt("请输入你的用户名");
if(result != null && result!=""){
document.getElementById("pp").innerHTML = result+",你好";
}
return result;
}

</script>


我们看代码:

mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
mBtn.setText(value);
}
});
}
});

... ...

private void textEvaluate(){
mSettings = mWebView.getSettings();
//让webView自适应屏幕
mSettings.setUseWideViewPort(true);
mSettings.setLoadWithOverviewMode(true);
mSettings.setLoadsImagesAutomatically(true);
//不支持缩放
mSettings.setSupportZoom(false);
//设置与JS交互的权限
mSettings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
mSettings.setJavaScriptCanOpenWindowsAutomatically(true);

mWebView.loadUrl("file:///android_asset/javascript.html");

mWebView.setWebChromeClient(new WebChromeClient(){
//拦截JS的prompt的对话框,其实这里应该弄一个dialog,让其输入
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

mBtn.setText(message);
result.confirm("VIVIAN");
return true;
}
});
}


效果:





JS调用Android代码

1,通过 WebView的addJavascriptInterface()进行对象映射

<script>

function callJS(){
//调用android的方法
test.hello("JS调用Android");
}

</script>


然后新建一个类:

public class AndroidtoJs {

private Context mContext;

public  AndroidtoJs(Context context){
mContext = context;
}

//必须加这个,代表JS要调用的
@JavascriptInterface
public  void  hello(String s){
Toast.makeText(mContext,s,Toast.LENGTH_SHORT).show();
Log.d("Hello",s);
}

}

... ...

private void testJStoAndroid(){
mSettings = mWebView.getSettings();
//让webView自适应屏幕
mSettings.setUseWideViewPort(true);
mSettings.setLoadWithOverviewMode(true);
mSettings.setLoadsImagesAutomatically(true);
//不支持缩放
mSettings.setSupportZoom(false);
//设置与JS交互的权限
mSettings.setJavaScriptEnabled(true);

mWebView.loadUrl("file:///android_asset/JStoAndroid.html");

mWebView.addJavascriptInterface(new AndroidtoJs(MainActivity.this),"test");

}






2:通过 WebViewClient 的方法shouldOverrideUrlLoading ()回调拦截 url

具体原理:

Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url

解析该 url 的协议

如果检测到是预先约定好的协议,就调用相应方法

<script>
function CallA(){

document.location = "http://www.baidu.com"
}

</script>


mWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

if(Uri.parse(url).getHost().equals("www.baidu.com")){
mWebView.loadUrl(url);
return  true;
}

return false;
}
});






3:通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

在JS中,有三个常用的对话框方法:

方法作用返回值备注
alert()弹出警告框没有在文本加入\n可换行
confirm()弹出确认框两个返回值返回布尔值,true表示点击了确认,false表示点击了取消
prompt()弹出输入框任意设置返回值点击确认:返回值为输入框中的值;点击取消,返回null
方式3的原理:Android通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调分别拦截JS对话框

(即上述三个方法),得到他们的消息内容,然后解析即可。

想要弹框,需要

// 设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);


三种方法的对比&使用场景:



最后附上项目地址:

https://github.com/vivianluomin/PracticeEveryDay/tree/master/WebViewandJavaScripter
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android webview