Android WebView加载服务端JS进行交互

交互的方式

  • 1、Android调用JS代码
    1.1、通过WebView 的 loadUrl(String url);
    1.2、通过WebView 的 evaluateJavascript(String script, ValueCallback resultCallback);

  • 2、JS调用Android代码
    2.1、通过Android WebView 提供的 addJavascriptInterface() 进行对象映射
    2.2、通过Android WebViewClient() 的 shouldOverrideUrlLoading() 进行URL拦截
    2.3、通过Android WebChromeClient() 提供的onJsAlert()、onJsConfirm()、onJsPrompt() 方法回调拦截JS对话框alert()、confirm()、prompt() 消息( 即 jsBridge运用)

栗子

首先贴出服务端JS代码

/***用NodeJS 搭建的一个简单的服务器,*主要是用于Get请求返回一个HTML网页*从而便于我们Android 和 JS 交互**/var express = require("express");var query= require("querystring");var app = express();app.use(express.static('public'));//我们要请求的网页var LogGet = require("./loginGet");//get请求返回HTML网页logGet = new LogGet();logGet.get(app);//这部分是执行POST请求代码,与本栗无关//var Mess = require("./login");//post请求,返回JSON数据//mess = new Mess();//mess.post(app,query);var server = app.listen(3000,function () {    var host = server.address().address;    var port = server.address().port;    console.log("应用实例,访问地址为 http://%s:%s", host, port)})复制代码

loginGet.js文件代码

** * 模拟get请HTML页面 * 以及HTML表单提交(get) * @constructor */function LogGet() {    this.get = function get(app) {        /**         * 当我们请求URL = "http://localhost:3000/index.html"         * 直接访问index.html         */        app.get("/index.html",function (req, res) {});        /**         * 用户HTML表单信息提交的响应,与本栗暂无关         */        app.get("/process_get",function (req, res) {            if (req.query.first_name == "q" && req.query.last_name =="q"){                res.sendFile(__dirname+"/"+"index.html");            }else {                // 输出 JSON 格式                var response = {                    "first_name":req.query.first_name,                    "last_name":req.query.last_name                };                console.log(response);                res.end(JSON.stringify(response));            }        })    }}module.exports = LogGet;复制代码

Android 调用JS代码

index.html文件代码

"en">    "UTF-8">    Title    "width: 400px;height: 400px;background-color: aqua;align-self: center;align-content: center" id="div">                    复制代码

接下来贴出Android代码
MainActivity.java

  @RequiresApi(api = Build.VERSION_CODES.KITKAT)    private void initView() {        mButton = findViewById(R.id.btn);        mWebView = findViewById(R.id.webview);        WebSettings webSettings = mWebView.getSettings();        // 设置与Js交互的权限        webSettings.setJavaScriptEnabled(true);        // 设置允许JS弹窗        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);        // 设置 WebViewClient        mWebView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {                //此方法一般用于拦截web页面中的URL 用于重定向加载                                return super.shouldOverrideUrlLoading(view, request);            }        });        mWebView.loadUrl("http://localhost:3000/index1.html");    }    private void androidToJS() {        mButton.setOnClickListener(new View.OnClickListener() {            @RequiresApi(api = Build.VERSION_CODES.KITKAT)            @Override            public void onClick(View v) {                //Android 调用 JS 方法                //Sdk小于4.4 时不可用                mWebView.evaluateJavascript("javascript:onBtnClick()", new ValueCallback() {                    @Override                    public void onReceiveValue(String value) {                        //js返回值                    }                });            }        });    }复制代码

JS调用Android代码

index.html文件代码

"en">    "UTF-8">    Title    "width: 400px;height: 400px;background-color: aqua;align-self: center;align-content: center" id="div">            复制代码

MainActivity.java代码

  @RequiresApi(api = Build.VERSION_CODES.KITKAT)    private void initView() {        mButton = findViewById(R.id.btn);        mWebView = findViewById(R.id.webview);        WebSettings webSettings = mWebView.getSettings();        // 设置与Js交互的权限        webSettings.setJavaScriptEnabled(true);        // 设置允许JS弹窗        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);                mWebView.loadUrl("http://localhost:3000/index.html");    }    private void jsToAndroid() {        // js 调用Android 代码方法        //敲黑板!!!!!        //此处的第一个参数是为一个对象,这个对象中的方法就是我们JS中要调用的方法        //第二个参数是String name 为约定名        //这两个名字必须和JS代码中一直,也就是说我们在开发时,这个是我们要和后端约定滴!!!!!        mWebView.addJavascriptInterface(new AndroidJS(),"android");    }    class AndroidJS{        //必须加此注解,否则不可用        @JavascriptInterface        public void jsHello(){            Toast.makeText(Main3Activity.this,"走你",Toast.LENGTH_LONG).show();        }    }复制代码

到目前为止,几个简单的交互方式代码都已经贴上。还有最后一个拦截prompt()(一般最主要第拦截prompt()输入框传值),这个,我印象中万能的Github中有好多JSBridge框架就是利用这个原理实现的,非要说原理,我感觉可像线程间通讯机制,JSBridge相当于Handler(在总体功能上说),Native通过既定的协议(这个必须要有)由JSBridge中转发至JS中,反过来也是类似。应该像极了Handler,MessageQueue,Message,这个Message就是我们规定的协议内容,JSBridge 就是从这个MessageQueue中来回取、存协议消息进行转发。
嗯,就这么多吧,以上这个原理可能存在很多不对的地方,具体源码没怎么看,只是印象中大致这么了解的,如有不对,往大家指出【抱拳】【抱拳】【抱拳】

转载于:https://juejin.im/post/5cadb942f265da03a1581260

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. android 反射静态方法传值
  3. Android拖动图片及多层图片叠加
  4. Android百度地图开发
  5. 【Android(安卓)开发教程】获取预设信息
  6. Android(安卓)SearchView设置与用法的那点事儿
  7. Drawable、Bitmap、byte[]之间的转换 (转)
  8. eclipse中跳转查看android类的源码
  9. PopupWindow与PopupMenu的用法

随机推荐

  1. 教你使用Android(安卓)SDK布局优化工具la
  2. 配置android的测试环境
  3. android中Handler详解
  4. 国内各大安卓(Android)市场的上传方式、认
  5. Android(安卓)涂鸦最佳实践
  6. Android之socket
  7. Android开发实践:JNI函数签名生成器
  8. Android手机软件汉化教程---第四课 dex文
  9. Android(安卓)2.1 中 JNI 层 camera 的应
  10. android软件中自定义设置字体