WebView的使用以及Android与Js的交互

来源:互联网 发布:方腊手下大将排名 知乎 编辑:程序博客网 时间:2024/04/30 04:43

WebView的官方文档地址:https://developer.android.com/reference/android/webkit/WebView.html

1.WebView基础使用

1.想要使用WebView,需要在<manifest>中添加权限:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <uses-permission android:name="android.permission.INTERNET" />  
2.我们可以在xml文件中使用<WebView>控件,也可以在我们自己的activity中直接创建
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. WebView webview = new WebView(this);  
  2. setContentView(webview);  
3.我们想要根据WebView来做一些自己的操作,一般通过两个事件来处理,分别是WebViewClient和WebChromeClient。

(1).WebChromeClient主要可以监听进度条的改变,或者alert的显示;相关方法查看文档(https://developer.android.com/reference/android/webkit/WebChromeClient.html)

(2).WebViewClient可以提供页面加载各个阶段的回调,包括onPageStarted()和onPageFinished()等方法,也可以调用shouldOverrideUrlloading()来拦截url。这段代码还有一个作用,就是当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前WebView中,而不是打开系统浏览器。相关方法查看文档(https://developer.android.com/reference/android/webkit/WebViewClient.html)

4.我们想要实现Android和js的交互,必须获得一个WebSettings对象,调用setJavaScriptEnabled()方法,

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. webview.getSettings().setJavaScriptEnabled(true);  
5.加载网页调用loadUrl(str)方法
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. webview.loadUrl("http://developer.android.com/");  

可以传入一个网络地址,也可以传入一个本地的html资源文件。

6.webview加载微信公众号连接,“阅读原文”无响应

由于dom内存没有启用,所以导致了js加载失败

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. getSettings().setDomStorageEnabled(true);  

7.webview获得内容长度

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. //        getContentHeight 返回的是整个html 的高度,但并不等同于当前整个页面的高度,  
  2. //        因为WebView 有缩放功能, 所以当前整个页面的高度实际上应该是原始html 的高度再乘上缩放比例.  
  3. //        因此,更正后的结果,准确的判断方法应该是:  
  4.         mWebView.getContentHeight()*mWebView.getScale();  

http://blog.csdn.net/t12x3456/article/details/13769731/#comments


2.Android调用Js

只需要在loadUrl里面的参数格式为“JavaScript:方法名()”,例如,html中有一个方法名叫做javaCallJs(),在android中调用这个方法的代码如下:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. mWebView.loadUrl("javascript:javaCallJs()");  
实现如下效果:


JavaCallJsActivity.Java

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package com.example.android_js;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.webkit.WebChromeClient;  
  7. import android.webkit.WebView;  
  8. import android.widget.Button;  
  9.   
  10. /** 
  11.  * Created by jian on 2016/10/31. 
  12.  */  
  13. public class JavaCallJsActivity extends Activity {  
  14.   
  15.     private Button btn1, btn2, btn3;  
  16.     private WebView mWebView;  
  17.   
  18.     @Override  
  19.     protected void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.activity_javacalljs1);  
  22.   
  23.         initView();  
  24.   
  25.         // 设置webview的javascript可用  
  26.         mWebView.getSettings().setJavaScriptEnabled(true);  
  27.         // 加载html,可网络,可本地  
  28.         mWebView.loadUrl("file:///android_asset/JavaCallJs.html");  
  29.         // 不加下面这句话,是无法调起alert的  
  30.         mWebView.setWebChromeClient(new WebChromeClient());  
  31.     }  
  32.   
  33.     private void initView() {  
  34.         btn1 = (Button) findViewById(R.id.java_call_js1_btn1);  
  35.         btn2 = (Button) findViewById(R.id.java_call_js1_btn2);  
  36.         btn3 = (Button) findViewById(R.id.java_call_js1_btn3);  
  37.         mWebView = (WebView) findViewById(R.id.java_call_js1_webview);  
  38.   
  39.         btn1.setOnClickListener(mOnClickListener);  
  40.         btn2.setOnClickListener(mOnClickListener);  
  41.         btn3.setOnClickListener(mOnClickListener);  
  42.     }  
  43.   
  44.     View.OnClickListener mOnClickListener = new View.OnClickListener() {  
  45.         @Override  
  46.         public void onClick(View v) {  
  47.             switch (v.getId()) {  
  48.                 case R.id.java_call_js1_btn1:  
  49.                     mWebView.loadUrl("javascript:javaCallJsNoArgs()");  
  50.                     break;  
  51.                 case R.id.java_call_js1_btn2:  
  52.                     mWebView.loadUrl("javascript:javaCallJsExistArgs('我是聂建')");  
  53.                     break;  
  54.                 case R.id.java_call_js1_btn3:  
  55.                     mWebView.loadUrl("javascript:showAlert('出现了alert!')");  
  56.                     break;  
  57.             }  
  58.         }  
  59.     };  
  60.   
  61. }  
activity_javacalljs1.xml
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.               android:layout_width="match_parent"  
  4.               android:layout_height="match_parent"  
  5.               android:orientation="vertical"  
  6.               android:padding="10dp">  
  7.   
  8.     <Button  
  9.         android:id="@+id/java_call_js1_btn1"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:text="java调用js无参方法"/>  
  13.   
  14.     <Button  
  15.         android:id="@+id/java_call_js1_btn2"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="java调用js有参方法"/>  
  19.   
  20.     <Button  
  21.         android:id="@+id/java_call_js1_btn3"  
  22.         android:layout_width="match_parent"  
  23.         android:layout_height="wrap_content"  
  24.         android:text="java调用js的dialog"/>  
  25.   
  26.     <WebView  
  27.         android:id="@+id/java_call_js1_webview"  
  28.         android:layout_width="match_parent"  
  29.         android:layout_height="match_parent"/>  
  30.   
  31. </LinearLayout>  
JavaCallJs.html
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html>  
  3.   
  4.     <head>  
  5.         <meta charset="UTF-8">  
  6.         <title>Java调用JavaScript</title>  
  7.         <style>  
  8.             #javacalljs1,  
  9.             #javacalljs2 {  
  10.                 color: red;  
  11.             }  
  12.         </style>  
  13.         <script type="text/javascript">  
  14.             function javaCallJsNoArgs() {  
  15.                 document.getElementById("javacalljs1").innerHTML += "Java调用了我的无参函数<br\>";  
  16.             }  
  17.   
  18.             function javaCallJsExistArgs(args) {  
  19.                 document.getElementById("javacalljs2").innerHTML += "Java调用了我的有参函数,参数是:" + args + "<br\>";  
  20.             }  
  21.   
  22.             function showAlert(args) {  
  23.                 alert(args);  
  24.             }  
  25.         </script>  
  26.     </head>  
  27.   
  28.     <body>  
  29.         这是NieJian写的Java调用Js的验证页面!<br /><br /> 点击按钮:“java调用js无参方法”。会出现以下内容:  
  30.         <br />  
  31.         <div id="javacalljs1"></div><br /><br /> 点击按钮:“java调用js有参方法”。会出现以下内容:  
  32.         <br />  
  33.         <div id="javacalljs2"></div>  
  34.     </body>  
  35.   
  36. </html>  

3.Js调用Android

Js调用Android,首先要在android代码中注册一个对象,调用如下方法:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void addJavascriptInterface (Object object,String name)  
[plain] view plain copy 在CODE上查看代码片派生到我的代码片
  1. Object: the Java object to inject into this WebView's JavaScript context. Null values are ignored.  
  2. String: the name used to expose the object in JavaScript  
这个方法是将object这个java对象注入到webview中,然后在webview中通过name这个字段来唯一标识调用object这个java对象中的方法。
[plain] view plain copy 在CODE上查看代码片派生到我的代码片
  1.  For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with   
  2. JavascriptInterface can be accessed from JavaScript. For applications targeted to API level JELLY_BEAN or below,   
  3. all public methods (including the inherited ones) can be accessed  
根据文档介绍,API17开始,就必须添加 @JavascriptInterface 注解,,而且方法必须是public修饰,否则,不生效,API16及以下的public方法可以不添加注解。
[plain] view plain copy 在CODE上查看代码片派生到我的代码片
  1. class JsObject {  
  2.     @JavascriptInterface  
  3.     public String toString() { return "injectedObject"; }  
  4.  }  
  5.  webView.addJavascriptInterface(new JsObject(), "injectedObject");  
  6.  webView.loadData("", "text/html", null);  
  7.  webView.loadUrl("javascript:alert(injectedObject.toString())");  
下面是一个小案例,实现效果如下:

JsCallJavaActivity.java

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. package com.example.android_js;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.webkit.JavascriptInterface;  
  6. import android.webkit.WebSettings;  
  7. import android.webkit.WebView;  
  8.   
  9. /** 
  10.  * Created by jian on 2016/10/31. 
  11.  */  
  12. public class JsCallJavaActivity extends Activity {  
  13.   
  14.     private WebView mWebView;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_javacalljs2);  
  20.   
  21.         initWebView();  
  22.     }  
  23.   
  24.     private void initWebView() {  
  25.         mWebView = (WebView) findViewById(R.id.java_call_js2_webview);  
  26.         WebSettings webSettings = mWebView.getSettings();  
  27.         webSettings.setJavaScriptEnabled(true);  
  28.         webSettings.setDefaultTextEncodingName("utf-8");  
  29.   
  30.         // 添加一个对象,让js对象可以访问该对象的方法  
  31.         mWebView.addJavascriptInterface(new MyObject(), "niejian_android");  
  32.         mWebView.loadUrl("file:///android_asset/JsCallJava.html");  
  33.     }  
  34.   
  35.     class MyObject {  
  36.         /** 
  37.          * API 17必须添加 @JavascriptInterface注解,否则会导致反射失败,调用无效 
  38.          */  
  39.         @JavascriptInterface  
  40.         public void javaCallJsMethod1() {  
  41.             runOnUiThread(new Runnable() {  
  42.                 @Override  
  43.                 public void run() {  
  44.                     mWebView.loadUrl("javascript:javaCallJsNoArgs()");  
  45.                 }  
  46.             });  
  47.         }  
  48.   
  49.         @JavascriptInterface  
  50.         public void javaCallJsMethod2() {  
  51.             runOnUiThread(new Runnable() {  
  52.                 @Override  
  53.                 public void run() {  
  54.                     mWebView.loadUrl("javascript:javaCallJsExistArgs('我是聂建')");  
  55.                 }  
  56.             });  
  57.         }  
  58.     }  
  59. }  
JsCallJava.html
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html>  
  3.   
  4.     <head>  
  5.         <meta charset="UTF-8">  
  6.         <title>JavaScript调用Java</title>  
  7.         <style>  
  8.             #content1,  
  9.             #content2 {  
  10.                 color: red;  
  11.             }  
  12.         </style>  
  13.         <script type="text/javascript">  
  14.             function javaCallJsNoArgs() {  
  15.                 document.getElementById("content1").innerHTML = "js调用java,Java再回调js的无参方法"  
  16.             }  
  17.   
  18.             function javaCallJsExistArgs(args) {  
  19.                 document.getElementById("content2").innerHTML = "js调用java,Java再回调js的无参方法,参数是:" + args;  
  20.             }  
  21.         </script>  
  22.     </head>  
  23.   
  24.     <body>  
  25.         这是NieJian写的Java调用Js的验证页面2!<br />  
  26.         <input type="button" value="JS->Java->JS “无参方法”,请点击,查看下方" onclick="window.niejian_android.javaCallJsMethod1()" /><br />  
  27.         <div id="content1"></div>  
  28.         <br /><br />  
  29.         <input type="button" value="JS->Java->JS “有参方法”,请点击,查看下方" onclick="window.niejian_android.javaCallJsMethod2()" /><br />  
  30.         <div id="content2"></div>  
  31.     </body>  
  32.   
  33. </html>  


0 0
原创粉丝点击