WebView与JS的交互
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 一、WebView与JS各自的含义
- 二、WebView与JS的交互方式
- 1.Android调用JS方法(2种方式)
- 2.JS调用Android方法(3种方式)
- 第一种方式`WebView.addJavascriptInterface()`的实现步骤
- 第二种方式`WebViewClient.shouldOverrideUrlLoading ()`的实现步骤
- 第三种方式`WebChromeClient`的实现步骤
一、WebView与JS各自的含义
- WebView在安卓中出现并不少见,尤其是需要访问网页的时候,如在APP上点击链接
- JS就是编写前端页面的代码,也就是网页的UI内容
像之前刚接触安卓的时候,没少看到安卓与JS交互写的一些方法代码,当时都是应付性的学习理解一下,并没有深入的学习和理解,所以今天趁着再一次学习, 把自己学的一些微小的见解写在博客上,方便后续学习。
二、WebView与JS的交互方式
大家如果想深入学习,可以看这一篇博客,内容更加具体,且下面图片出自该处
注:Android与JS的交互是可以通过本地文件和远程url的形式,而本文是采用Andorid调用本地JS代码说明;实际情况时,Android更多的是调用远程JS代码,即将加载的JS代码路径改成url即可
1.Android调用JS方法(2种方式)
注:因为webView是Android的控件之一,所以这样写成Android与JS的交互,而webview算是它们二者交互的桥梁。
- 第一种方式:WebView.loadUrl()
webView.loadUrl("javascript:callJS()")//当前是加载本地资源
- 第二种方式:WebView.evaluateJavascript()(比第一种更加高效)
// 只需要将第一种方法的loadUrl()换成下面该方法即可 mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); }
两种加载方式对比:
//注意结尾后面不需要斜杠 / CXJ //JS代码 function callJS(){ alert("Android调用了JS的callJS方法"); }
- 步骤2:布局文件:
- 步骤3:编写关键代码
//1.3先加载JS代码 规定格式:file:///android_asset/文件名.html webView.loadUrl("file:///android_asset/javascript.html");
注意:file:///android_asset/文件名.html 是加载本地JS文件的规定格式
//方法名要对应javascript.html文件里面的 callJS()函数 webView.loadUrl("javascript:callJS()");
完整的代码:
public class MainActivity extends AppCompatActivity { WebView webView; Button button; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); button=findViewById(R.id.button); //1.开始设置web View相关设置 WebSettings webSettings=webView.getSettings(); //1.1允许与JS发生交互 webSettings.setJavaScriptEnabled(true); //1.2允许设置JS弹窗 webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //1.3先加载JS代码 规定格式:file:///android_asset/文件名.html webView.loadUrl("file:///android_asset/javascript.html"); //2.点击事件 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { webView.post(new Runnable() { @Override public void run() { //第一种方式加载 //方法名要对应 callJS() // webView.loadUrl("javascript:callJS()"); //第二种方式加载 // webView.evaluateJavascript("javascript:callJS()", new ValueCallback() { // @Override // public void onReceiveValue(String s) { // Log.d("TAG", "js返回的结果: "+s); // } // }); //兼容上下版本更改的方式加载 // Android版本变量 final int version = Build.VERSION.SDK_INT; // 因为该方法在 Android 4.4 版本才可使用,所以使用时需进行版本判断 if (version
2.JS调用Android方法(3种方式)
第一种方式:WebView.addJavascriptInterface()
第二种方式:WebViewClient.shouldOverrideUrlLoading ()
第三种方式:WebChromeClient.addJavascriptInterface()
第一种方式WebView.addJavascriptInterface()的实现步骤
- 步骤1:编写给JS调用的安卓方法类AndroidToJs
/** 1. 定义给JS调用的安卓方法 */ public class AndroidToJs extends Object{ //定义给JS调用的安卓方法——且必须加上JavascriptInterface @JavascriptInterface public void hello(String msg){ System.out.println("JS调用安卓的Hello方法"); } }
CXJ function callAndroid(){ // 由于对象映射,所以调用test对象等于调用Android映射的对象 test.hello("js调用了android中的hello方法"); } //点击按钮则调用callAndroid函数 这一段代码是在JS界面设置好的,不需要在安卓的布局里面添加Button控件
- 步骤3:在Android里通过WebView设置Android类与JS代码的映射
关键代码:
//2.通过addJavascriptInterface将Java映射到JS对象 参数1:javascript对象名 参数2:Java对象名 webView.addJavascriptInterface(new AndroidToJs(),"test");
注:参数1:javascript对象名(提供给JS调用的类名) 参数2:javascript2.html里面的对象
完整的代码:
public class JSUseAndroid extends AppCompatActivity { WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_jsuse_android); webView = findViewById(R.id.webview); //1.开始设置web View相关设置 WebSettings webSettings=webView.getSettings(); //1.1允许与JS发生交互 webSettings.setJavaScriptEnabled(true); //2.通过addJavascriptInterface将Java映射到JS对象 参数1:javascript对象名 参数2:Java对象名 webView.addJavascriptInterface(new AndroidToJs(),"test"); //3.加载JS代码 webView.loadUrl("file:///android_asset/javascript2.html"); } }
效果展示:
第二种方式WebViewClient.shouldOverrideUrlLoading ()的实现步骤
原理:Android通过 WebViewClient的回调方法shouldOverrideUrlLoading ()拦截 url并解析该 url 的协议,如果检测到是预先约定好的协议,就调用相应方法。
//3.复写WebViewClient类的shouldOverrideUrlLoading方法 webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //3.1根据协议的参数,判断是否是所需要的url格式 //TODO 一般根据scheme(协议格式) & authority(协议名) 判断(前两个参数) "js://webview?arg1=111&arg2=222" Uri uri=Uri.parse(url); //3.2如果协议等于预先约定的js协议,则往下解析参数 if (uri.getScheme().equals("js")){ //3.3如果authority=预先约定好的webview,则表示都符合约定 if (uri.getAuthority().equals("webview")){ System.out.println("js调用了Android的方法"); //后续需要 HashMap params=new HashMap(); Set collection=uri.getQueryParameterNames();//获取 Uri 中的所有查询参数名称,并存储在 Set 集合中 } return true; } return super.shouldOverrideUrlLoading(view, url); } });
注:uri.getScheme()对应的是约定协议约定的url协议为:js://webview?arg1=111&arg2=222的js 部分 ,而 uri.getAuthority()对应的是webview
完整的代码:
public class JSUseAndroid2 extends AppCompatActivity { WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_jsuse_android2); webView = findViewById(R.id.webview); //1.开始设置web View相关设置 WebSettings webSettings=webView.getSettings(); //1.1允许与JS发生交互 webSettings.setJavaScriptEnabled(true); //2.加载JS代码 webView.loadUrl("file:///android_asset/javascript3.html"); //3.复写WebViewClient类的shouldOverrideUrlLoading方法 webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //3.1根据协议的参数,判断是否是所需要的url格式 //TODO 一般根据scheme(协议格式) & authority(协议名) 判断(前两个参数) "js://webview?arg1=111&arg2=222" Uri uri=Uri.parse(url); //3.2如果协议等于预先约定的js协议,则往下解析参数 if (uri.getScheme().equals("js")){ //3.3如果authority=预先约定好的webview,则表示都符合约定 if (uri.getAuthority().equals("webview")){ System.out.println("js调用了Android的方法"); //后续需要 HashMap params=new HashMap(); Set collection=uri.getQueryParameterNames();//获取 Uri 中的所有查询参数名称,并存储在 Set 集合中 } return true; } return super.shouldOverrideUrlLoading(view, url); } }); } }
效果展示:
第三种方式WebChromeClient的实现步骤
有三种形式:
- WebChromeClient.onJsAlert()
- WebChromeClient.onJsConfirm()
- WebChromeClient.onJsPrompt()
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { //3.1根据协议的参数,判断是否是所需要的url格式 //TODO 一般根据scheme(协议格式) & authority(协议名) 判断(前两个参数) "js://webview?arg1=111&arg2=222" Uri uri=Uri.parse(message);//TODO 这样传入的是promt()的内容 //3.2如果协议等于预先约定的js协议,则往下解析参数 if (uri.getScheme().equals("js")){ //3.3如果authority=预先约定好的webview,则表示都符合约定 if (uri.getAuthority().equals("demo")){ System.out.println("js调用了Android的方法"); //后续需要 HashMap params=new HashMap(); Set collection=uri.getQueryParameterNames();//获取 Uri 中的所有查询参数名称,并存储在 Set 集合中 //参数result:代表消息框的返回值(输入值) result.confirm("js调用Android方法成功啦"); } return true; } return super.onJsPrompt(view, url, message, defaultValue, result); }
完整代码:
public class JSuseAndroid3 extends AppCompatActivity { WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_jsuse_android3); webView = findViewById(R.id.webview); //1.开始设置web View相关设置 WebSettings webSettings=webView.getSettings(); //1.1允许与JS发生交互 webSettings.setJavaScriptEnabled(true); //1.2 允许设置JS弹窗 webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //2.加载JS代码 webView.loadUrl("file:///android_asset/javascript4.html"); //3.复写 webView.setWebChromeClient(new WebChromeClient(){ //拦截输入框 参数message:代表promt()的内容(不是url) 参数result:代表输入框的返回值 @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { //3.1根据协议的参数,判断是否是所需要的url格式 //TODO 一般根据scheme(协议格式) & authority(协议名) 判断(前两个参数) "js://webview?arg1=111&arg2=222" Uri uri=Uri.parse(message);//TODO 这样传入的是promt()的内容 //3.2如果协议等于预先约定的js协议,则往下解析参数 if (uri.getScheme().equals("js")){ //3.3如果authority=预先约定好的webview,则表示都符合约定 if (uri.getAuthority().equals("demo")){ System.out.println("js调用了Android的方法"); //后续需要 HashMap params=new HashMap(); Set collection=uri.getQueryParameterNames();//获取 Uri 中的所有查询参数名称,并存储在 Set 集合中 //参数result:代表消息框的返回值(输入值) result.confirm("js调用Android方法成功啦"); } return true; } return super.onJsPrompt(view, url, message, defaultValue, result); } //拦截JS的警告框 @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { return super.onJsAlert(view, url, message, result); } //拦截JS的确认框 @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { return super.onJsConfirm(view, url, message, result); } }); } }
效果图:
- 第二种方式:WebView.evaluateJavascript()(比第一种更加高效)
- 第一种方式:WebView.loadUrl()