安卓中WebView和原生的通信示例Demo(含完整源码)

本文详细介绍了WebView与原生Android应用之间的通信方式,包括原生调用JavaScript的loadUrl()和evaluateJavascript()方法,以及JavaScript调用原生的addJavascriptInterface()、shouldOverrideUrlLoading()和onJsPrompt()方法。提供了完整的Java和HTML代码示例,帮助开发者更好地理解和实现两者间的交互。

一、前言

所谓通信,说白了就是WebView和原生互相调用对方的函数、互相传值。WebView和原生通信的方式也很简单,不过最好是自己动手实现一下,才能够记得牢固。不管是面试还是笔试,都会经常考到。我也看过其他大佬的文章,不过有些地方没有给出必要的说明,让人看后还是不知道怎么实现,所以本文的最后会给出整个项目的源码,若有不清楚的地方,下载下来跑一遍就能够理解了。Demo的截图如下:
在这里插入图片描述

二、原生调用js

方法1:通过WebView对象的loadUrl()方法

loadUrl()方法不仅可以加载一个html网页,还可以调用js的方法,是不是很神奇呢!这里给出的例子是原生调用js的cat()方法,loadUrl()方式的缺点是不方便获取js方法的返回值,如果你给这个cat()方法返回一个值,你会发现html页面的body直接就展示这个返回值了,这显然不是你想要的结果吧。

原生java代码

mWebView.loadUrl("javascript:cat()");

html

let flag1 = true
function cat() {
   
   
            document.getElementById('div1').innerHTML = flag1 ? "小肥咪" : "大肥咪"
            flag1 = !flag1
        }

方法2:通过WebView对象的evaluateJavascript()方法

上面说了loadUrl()方式的缺点是不方便获取js方法的返回值,那么想要方便地获取js方法的返回值,可以使用evaluateJavascript()这个方法。

原生java代码

 mWebView.evaluateJavascript("javascript:sayHello()", new ValueCallback<String>() {
   
   
                    @Override
                    public void onReceiveValue(String value) {
   
   //可以在这个回调方法里面拿到js方法的返回值
                        Log.d(TAG, "onReceiveValue: "+value);
                    }
                });

html

let flag2 = true
 function sayHello() {
   
   
            document.getElementById("div2").innerHTML = flag2 ? "喵喵喵喵叫" : "嗷嗷叫"
            flag2 = !flag2
            return "我是js方法的返回值"
        }

三、js调用原生

js调用原生的话,这里介绍3种方式。

方法1:通过WebView对象的addJavascriptInterface()方法

这种方法其实就是用了对象映射,使用起来也不复杂。我们需要写一个类,在里面写上自己的方法,再把@JavascriptInterface注解加到你的方法上面。addJavascriptInterface()这个方法接收两个参数,第一个参数直接new出来一个刚才你自定义的类的对象;addJavascriptInterface()方法的第二个参数是一个字符串,是可以自定义的,这里我直接自定义为"android",其实也就是js里面用到的,作为一个对象名。

原生java代码

//自定义一个类
class MyNative{
   
   
        @JavascriptInterface
        public void getNative1(String who){
   
   
            Log.d(TAG, "getNative1: "+who);
            Toast.makeText(MainActivity.this, "js通过对象映射addJavascriptInterface的方式调用了原生的方法", Toast.LENGTH_SHORT).show();
        }
    }
MyNative myNative = new MyNative();//不要使用匿名内部类放入addJavascriptInterface中
//让js调用原生的方法
 mWebView.addJavascriptInterface(myNative,"android");//这里的android也可以写成别的字符串,待会js里面需要用到这个名字

html

下面的android对应的就是原生java代码里面你取的对象名

<button class="btn" onclick="window.android.getNative1('张三')">addJavascriptInterafce</button>

方法2:通过重写WebViewClient对象的shouldOverrideUrlLoading()方法

shouldOverrideUrlLoading()这个方法返回true,可以将url拦截(不打开新的网页)。在js里面调用的话,我们其实是需要写上一个url的。在url上可以拼接一些参数,传给原生使用。

原生java代码

mWebView.setWebViewClient(new WebViewClient(){
   
   
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
   
   //js调用原生的方式二
                Log.d(TAG, "shouldOverrideUrlLoading: ");

                Uri url = request.getUrl();
                if (url!=null){
   
   
                    String schemenName = url.getScheme();//约定好的协议名称,这里我约定成了myscheme,经测试,协议名需要完全为小写字母
                    if ("myscheme".equals(schemenName)){
   
   
                        String authority = url.getAuthority();//约定好的地址名
                        if ("myAddress".equals(authority)){
   
   
                            String userName = url.getQueryParameter("userName");//获取用户名参数
                            String password = url.getQueryParameter("password");//获取密码参数
                            Log.d(TAG, "shouldOverrideUrlLoading: 获取到js传过来的用户名userName为:"+userName+",密码为:"+password);
                            Toast.makeText(MainActivity.
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值