Android(安卓)WebView加载服务端JS进行交互
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
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- android 反射静态方法传值
- Android拖动图片及多层图片叠加
- Android百度地图开发
- 【Android(安卓)开发教程】获取预设信息
- Android(安卓)SearchView设置与用法的那点事儿
- Drawable、Bitmap、byte[]之间的转换 (转)
- eclipse中跳转查看android类的源码
- PopupWindow与PopupMenu的用法