# WebViewAndJS **Repository Path**: housirvip/WebViewAndJS ## Basic Information - **Project Name**: WebViewAndJS - **Description**: No description available - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-09-21 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Android和H5、JS进行交互调用 >Android开发过程中,我们或多或少都会用到webview,使用webview来展示一些经常变动的界面更加方便简单,也更易于维护。另一方面hybrid App开发也现在用的也越来越多了,其中native和h5之间的交互更是必不可少的。Android中是如何和H5交互的?或者说Android中是如何和JS交互的? #### 一、webView加载页面 我们都知道在Android中是通过webView来加载html页面的,根据HTML文件所在的位置不同写法也不同: - 例如:加载assets文件夹下的test.html页面 ```java mWebView.loadUrl("file:///android_asset/index.html") ``` - 例如:加载网页 ``` mWebView.loadUrl("http://www.baidu.com") ``` 如果只是这样调用mWebView.loadUrl()加载的话,那么当你点击页面中的链接时,页面将会在你手机默认的浏览器上打开。那如果想要页面在App内中打开的话,那么就得设置setWebViewClient: ```java mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //我们可以在这里拦截特定的rl请求,然后进行自己要的操作 if (url.equals("file:///android_asset/test2.html")) { Log.e(TAG, "shouldOverrideUrlLoading: " + url); startActivity(new Intent(MainActivity.this,Main2Activity.class)); return true; } else { //这里我们自己重新加载新的url页面,防止点击链接跳转到系统浏览器 mWebView.loadUrl(url); return true; } } } }); ``` 重写Activity的onBackPressed方法,使得返回按钮不会关闭当前页面,而是返回webview的上一个历史页面: ```java @Override public void onBackPressed() { if (webView.canGoBack()) { //返回上一个页 webView.goBack(); return ; } super.onBackPressed(); } ``` #### 二、给webView添加加载新页面的进度条。 - 开启和关闭进度条: webView.setWebViewClient(new WebViewClient() { //重写页面打开和结束的监听。打开时弹出菊花,关闭时隐藏菊花 /** * 界面打开的回调 */ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } //弹出菊花 progressDialog = new ProgressDialog(JSActivity.this); progressDialog.setTitle("提示"); progressDialog.setMessage("软软正在拼命加载……"); progressDialog.show(); } /** * 界面打开完毕的回调 */ @Override public void onPageFinished(WebView view, String url) { //隐藏菊花:不为空,正在显示。才隐藏关闭 if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } } }); - 让进度条显示页面加载进度: ```java //设置进度条 //WebChromeClient与webViewClient的区别 //webViewClient处理偏界面的操作:打开新界面,界面打开,界面打开结束 //WebChromeClient处理偏js的操作 webView.setWebChromeClient(new WebChromeClient() { /** * 进度改变的回调 * WebView:就是本身 * newProgress:即将要显示的进度 */ @Override public void onProgressChanged(WebView view, int newProgress) { if (progressDialog != null && progressDialog.isShowing()) progressDialog.setMessage("软软正在拼命加载……" + newProgress + "%"); } ``` #### 三、Android本地通过Java调用HTML页面中的JavaScript方法 想要调用js方法那么就必须让webView支持 //首先设置Webview支持JS代码 webView.getSettings().setJavaScriptEnabled(true); 若调用的js方法没有返回值,则直接可以调用mWebView.loadUrl("javascript:do()");其中do是js中的方法;若有返回值时我们可以调用mWebView.evaluateJavascript()方法: ```java @TargetApi(Build.VERSION_CODES.KITKAT) public void onSum(View view){ webView.evaluateJavascript("sum(1,2)", new ValueCallback() { @Override public void onReceiveValue(String value) { Toast.makeText(getApplicationContext(), "相加结果:"+value, Toast.LENGTH_SHORT).show(); } }); } public void onDoing(View view){ String msg = "测试"; webView.loadUrl("javascript:showInfoFromJava('"+msg+"')"); } ``` 对应的JS方法: ```java function sum(a,b){ return a+b; } function showInfoFromJava(){ document.getElementById("p").innerHTML="Java成功调的JS方法"; } ``` #### 四、js调用Android本地Java方法 在Android4.2以上可以直接使用@JavascriptInterface注解来声明,下面是在一个本地Java方法 ```java public void addJavascriptInterface(Object object, String name); ``` - 1.object参数:在object对象里面添加我们想要在JS里面调用的Android方法,下面的代码中我们调用了showToast方法 - 2.name参数:这里的name就是我们可以在JS里面调用的对象名称,对应下面代码中的JSTest 对应的JS代码: ```js function jsJava(){ //调用java的方法,顶级对象,java方法 //可以直接访问JSTest,这是因为JSTest挂载到js的window对象下了 JSTest.showToast("我是被JS执行的Android代码"); } ``` 对应的Java代码: ```java //java与js回调,自定义方法 //1.java调用js //2.js调用java //首先java暴露接口,供js调用 /** * obj:暴露的要调用的对象 * interfaceName:对象的映射名称 ,object的对象名,在js中可以直接调用 * 在html的js中:JSTest.showToast(msg) * 可以直接访问JSTest,这是因为JSTest挂载到js的window对象下了 */ webView.addJavascriptInterface(new Object() { //定义要调用的方法 //msg由js调用的时候传递 @JavascriptInterface public void showToast(String msg) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } }, "JSTest"); ``` #### 五、重绘alert、confirm和prompt的弹出效果,并把用户具体的操作结果回调给JS - alert弹窗: ![alert弹窗](picture/alert.png) - 重绘confirm弹窗: ![confirm弹窗](picture/confirm.png) - 重绘prompt弹窗: ![prompt弹窗](picture/prompt.png) #### 五、效果图以及代码布局文件: ![效果图](picture/GIF.gif))