Android(安卓)WebView与Js的交互
16lz
2021-12-04
Android调用JS中的方法
- view.loadUrl(“javascript:callJs(\”Android传递数据给js\”);”);
- view.evaluateJavascript
在html中有以下内容:
//Android需要调用的方法,str由Android端传递来 function callJs(str){ alert("Android调用了JS的callJS方法,获得来自Android端的数据:"+str); } //Android需要调用的方法,str由Android端传递来,此函数的返回值由Android端接收 function callJsByEval(str){ alert("Android调用了JS的callJS方法,获得来自Android端的数据:"+str); return "js 返给 Android"; }
在Android端
在Activity的onCreate中调用webView.loadUrl("http://192.168.0.164:8080/bootstrap_sign_in.html");WebSettings mSettings = webView.getSettings();mSettings.setJavaScriptEnabled(true);//开启javascriptwebView.setWebViewClient(new Clientweb());//继承WebClient的类private class Clientweb extends WebViewClient{ /** * 页面加载完成回调的方法 */ @Override public void onPageFinished(final WebView view, String url) { super.onPageFinished(view, url); //JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用 //4.4以下使用此方法 无法获得js的返回值 view.loadUrl("javascript:callJs(\"Android传递数据给js\");"); //4.4以上使用此方法,可以获得js的返回值 view.evaluateJavascript("javascript:callJsByEval(\"Android传递数据给js eval\")", new ValueCallback() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 Toast.makeText(view.getContext(),value,Toast.LENGTH_LONG).show(); } }); } }
JS调用Android代码
- 使用注解@JavascriptInterface
- 在shouldOverrideUrlLoading里面拦截url
- 在onJsPrompt,onJsAlert,onJsConfirm里面拦截url
使用注解@JavascriptInterface
新建一个类,需要js调用的方法要加上注解@JavascriptInterface,如下所示:
import android.webkit.JavascriptInterface;import android.webkit.WebView;import android.widget.Toast;public class Js { private WebView webView; public Js(WebView webView) { this.webView = webView; } @JavascriptInterface public void showA(String intentid_str) { Toast.makeText(webView.getContext(),intentid_str,Toast.LENGTH_LONG).show(); } @JavascriptInterface public void showB(String intentid_str) { Toast.makeText(webView.getContext(),intentid_str,Toast.LENGTH_LONG).show(); }}
通过WebView调用:
webView.loadUrl("http://192.168.0.164:8080/bootstrap_sign_in.html");WebSettings mSettings = webView.getSettings();mSettings.setJavaScriptEnabled(true);//开启javascriptwebView.setWebViewClient(new Clientweb());Js javaJs=new Js(webView);webView.addJavascriptInterface(javaJs,"external");
html中对应的内容,相关的字符串必须保持一致,比如这里的external,showA,showB
"javascript:window.external.showA('js调用Android中的showA方法');">2017-2018
function callAndroid(){ external.showB("js调用了android中的showB方法"); }
在shouldOverrideUrlLoading里面拦截url
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { Uri uri = Uri.parse(request.getUrl().toString()); // 通过解析Uri进行逻辑判断,只对预先协商好的协议响应 if ( uri.getScheme().equals("js")) { if (uri.getAuthority().equals("method1")) {//响应协议上的method1方法:js://method1?arg1=111&arg2=222 // 获取js传递过来的参数 Set collection = uri.getQueryParameterNames(); StringBuilder stringBuilder=new StringBuilder(); for (String str : collection) { stringBuilder.append(str); stringBuilder.append(":"); stringBuilder.append(uri.getQueryParameter(str)); stringBuilder.append(","); } Toast.makeText(view.getContext(),"js调用了Android的方法,获取的js传递的参数是:"+stringBuilder.toString().substring(0,stringBuilder.toString().length()-1),Toast.LENGTH_LONG).show(); }else if(uri.getAuthority().equals("method2")){ //响应协议上的method1方法:js://method2?arg1=111&arg2=222 // 获取js传递过来的参数 Set collection = uri.getQueryParameterNames(); StringBuilder stringBuilder=new StringBuilder(); for (String str : collection) { stringBuilder.append(str); stringBuilder.append(":"); stringBuilder.append(uri.getQueryParameter(str)); stringBuilder.append(","); } Toast.makeText(view.getContext(),"js调用了Android的方法,获取的js传递的参数是:"+stringBuilder.toString().substring(0,stringBuilder.toString().length()-1),Toast.LENGTH_LONG).show(); } return true; } return super.shouldOverrideUrlLoading(view, request); }
在onJsPrompt,onJsAlert,onJsConfirm里面拦截url
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { Uri uri = Uri.parse(message); // 通过解析Uri进行逻辑判断,只对预先协商好的协议响应 if ( uri.getScheme().equals("js")) { if (uri.getAuthority().equals("prompt")) {//响应协议上的prompt方法:js://prompt?arg1=111&arg2=222 // 获取js传递过来的参数 Set collection = uri.getQueryParameterNames(); StringBuilder stringBuilder=new StringBuilder(); for (String str : collection) { stringBuilder.append(str); stringBuilder.append(":"); stringBuilder.append(uri.getQueryParameter(str)); stringBuilder.append(","); } result.confirm("js调用了Android的方法,获取的js传递的参数是:"+stringBuilder.toString().substring(0,stringBuilder.toString().length()-1)); //Toast.makeText(view.getContext(),"js调用了Android的方法,获取的js传递的参数是:"+stringBuilder.toString().substring(0,stringBuilder.toString().length()-1),Toast.LENGTH_LONG).show(); } return true; } return super.onJsPrompt(view, url, message, defaultValue, result); }
使用到了html的关键代码
<body class="text-center"> <form class="form-signin"> <img class="mb-4" src="bootstrap-solid.svg" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" onclick="clickprompt();">拦截prompt调用Android端方法h1> <label for="inputEmail" class="sr-only">Email addresslabel> <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Passwordlabel> <input type="password" id="inputPassword" class="form-control" placeholder="Password" required> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" onchange="toggleCheckbox(this)">响应服务端的alert label> div> <button class="btn btn-lg btn-primary btn-block" type="submit" onclick="callAndroid()">注解调用Android端方法1button> <p class="text-muted"><a href="javascript:window.external.showA('js调用Android中的showB方法');">注解调用Android端方法2a>p> <p class="text-muted"><a href="js://method1?arg1=111&arg2=222">拦截url调用Android端方法1a>p> <p class="text-muted"><a href="js://method2?arg1=中国&arg2=天数奇谭">拦截url调用Android端方法2a>p> form> <script> function toggleCheckbox(element){ var aa=element.checked; var s=aa ? "选中了" : "取消了"; alert(s); } //Android需要调用的方法 function callJs(str){ alert("Android调用了JS的callJS方法,获得来自Android端的数据:"+str); } //Android需要调用的方法 function callJsByEval(str){ alert("Android调用了JS的callJS方法,获得来自Android端的数据:"+str); return "js 返给 Android"; } function callAndroid(){ external.showA("js调用了android中的showA方法"); } function clickprompt(){ // 调用prompt() var result=prompt("js://prompt?arg1=111&arg2=222"); alert(result);} script> body>
参考:
https://blog.csdn.net/carson_ho/article/details/64904691?locationNum=2
更多相关文章
- Android点滴(9) -- Android(安卓)不显示标题栏和全屏的设置方法
- Android(安卓)控件:使用下拉列表框--Spinner
- Android(安卓)SDK4.0离线快速安装方法
- Android与Unity交互研究
- Android多进程之Binder的使用
- Android的UI书写的四种方法
- android 让一个控件按钮居于底部的几种方法
- Android热更新九:Robust热更新原理
- Android热更新二:理解Java反射