WebView动态运行android代码,WebView(H5)调用Android端代码

本文详细介绍了如何通过WebView在Android应用中实现与H5页面的交互,包括通过addJavascriptInterface()、shouldOverrideUrlLoading()以及WebChromeClient的alert()、prompt()、confirm()方法。通过实例代码展示了三种方式的使用,同时强调了方法的安全性和注意事项,为开发者提供了清晰的参考指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebView调用Android代码

做好战斗准备,其实也不复杂

情景再现:

运营的H5页面上有个按钮,叫“立即参加”,当用户点击按钮的时候,App上要弹一个吐司出来。

一、通过WebView的addJavascriptInterface ()方式进行映射

1.准备工作

定义我们将来要响应js代码的类

/**

* 与h5交互的共同类

*/

public class ForJs {

//添加注解,不添加注解方法不能够被js调用

//注意方法名称,提供给js的时候也一定要匹配

@JavascriptInterface

public void fromAndroid(){

//我们具体要执行的逻辑,本例只是弹一个吐司

ToastUtil.showToast("这个是android里的方法");

}

// 同上,只是一个有参,一个无参而已

@JavascriptInterface

public void fromAndroid(String msg){

//我们具体要执行的逻辑,本例只是弹一个吐司

ToastUtil.showToast("msg");

}

}

至此,准备工作就已经结束。

2.使用

android端代码

//如果只需要让js调用android代码,这几行就够了

WebSettings settings = mWebView.getSettings();

settings.setJavaScriptEnabled(true);

mWebView.addJavascriptInterface(new ForJs(), "testMall");

参数说明:

1、我们定义的与H5交互的java类

2、java类在H5中映射的对象名称

H5中的js在调用我们的方法的时候,必须知道的是:

映射对象的名称,即示例中的testMall

映射对象提供的方法名称,即示例中的ForJs类中的fromAndroid()

H5中的关键代码

注意这部分代码并不需要我们Android端人员编写,但是却需要我们Android端人员的配合

//js中的点击方法调用,调用的是Android端的无参方法

//js中方法的定义

function test(){

testMall.fromAndroid()//注意 testMall 对象,以及fromAndroid()方法名称

}

重复一下注意事项:

Androdi端提供给js调用的方法名称要准确无误的告诉前端人员

Js中映射的Java对象名称,要准确无误的告诉Android端人员

一定要看

二、通过WebViewClinet的shouldOverrideUrlLoading()方法拦截url

拦截该Url

解析Url协议()//新的API可以直接获取到uri

按照约定调用Android端的方法

1.Android端代码

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

WebSettings settings = mWebView.getSettings();

settings.setJavaScriptEnabled(true);

mWebView.setWebViewClient(new WebViewClient(){

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

//请求方式

String method = request.getMethod();

//请求头

Map requestHeaders = request.getRequestHeaders();

//uri,给里面有各种我们需要的东西,只需要get即可

Uri uri = request.getUrl();

String host = uri.getHost();

String authority = uri.getAuthority();

// TODO: 2018/12/15 判断,如果符合约定,即执行Android提供好的方法,最后记得return true

//模拟微信封杀抖音链接

if (authority.contains("douyin")){

ToastUtil.showToast("不要看抖音,微信不够丰富吗");

return true;

}

return super.shouldOverrideUrlLoading(view, request);

}

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

//如果使用这个方法,那么需要自己手动获取uri,其实与上面并无本质区别

Uri uri = Uri.parse(url);

return super.shouldOverrideUrlLoading(view, url);

}

});

至此,Android端代码完成

2.H5端代码

注意这部分代码并不需要我们Android端人员编写,但是却需要我们Android端人员与H5端人员协商好协议约定

//js中的点击方法调用

//js中方法的定义

function test(){

document.location="https://www.douyin.com/"

}

与第一种方法比起来,这种写法双方写起来都比较随意。除了Url的协议约定外,别的没有需要注意事项。尤其H5端,其实只是重定向了一个网页而已。

换句话说,在本示例中,如果我们直接在webView中加载https://www.douyin.com/,也会触发我们的Android中的方法,即拦截逻辑。

更重要的是,第二种方式没有第一种方式那种致命漏洞。即利用shouldOverrideUrlLoading方法不存在漏洞

缺点:难以获得返回值,如果想要获得返回值,那么就利用Android端调用Js的方法webView的loadUrl(restul),将Android端的返回值result当做参数传递给js。

Android端示例代码:

WebSettings settings = mWebView.getSettings();

settings.setJavaScriptEnabled(true);

mWebView.setWebViewClient(new WebViewClient() {

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

Uri uri = request.getUrl();

String authority = uri.getAuthority();

//模拟代码

if (authority.contains("douyin")) {

String result = "这是Android端执行完成之后的结果";

//获取android端的结果后调用js中的方法,把result当参数传递给js

mWebView.loadUrl("javascript:callJsFromAndroid("+result+")");

return true;

}

return super.shouldOverrideUrlLoading(view, request);

}

});

//注意,本示例之所以加此行代码,是为了能弹出js框,具体要看实际需求

mWebView.setWebChromeClient(new WebChromeClient());

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

H5端示例代码

//result是android端的处理结果

function callJsFromAndroid(result){

alert(result)

}

三、通过WebChromeClient的alert()、prompt()、confirm()方法回调js对应的对话框

我在https://www.jianshu.com/p/22265f5c5d78中详细介绍了Android端响应这三种js弹框的方式,如果不熟悉的请先了解一下。一般来将,我们使用的最多的是prompt()方法,因为这个有任意类型的返回值,请看示例代码

Android端代码

WebSettings settings = mWebView.getSettings();

settings.setJavaScriptEnabled(true);

//本行代码添加只是为了让网页在app内打开

mWebView.setWebViewClient(new WebViewClient());

mWebView.setWebChromeClient(new WebChromeClient(){

@Override

public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

//message即是js弹框中的内容

//解析message,按照约定处理逻辑

if (TextUtils.equals(message,"douyin")) {

// android端的处理逻辑

ToastUtil.showToast("你们怎么都那么好看又有钱");

return true;

}

return super.onJsPrompt(view, url, message, defaultValue, result);

}

});

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

H5端示例代码

//js中的点击方法调用

function test(){

prompt("douyin")

}

三种使用方式的对比

1.比较简单,但存在致命漏洞

2.需要双方约定协议,但不存在漏洞

3.与方式2很相似,只是拦截对象不同,也不存在漏洞

写在最后

这些交互方式各有特点,而且并不难以理解,个人认为都应该掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值