webView 与 Android交互详解

21 篇文章 0 订阅
6 篇文章 0 订阅

一: webView相关知识:

1 WebView是一个基于webkit引擎、展现web页面的控件。
2 常用类及方法:


 WebSettings类,对WebView进行配置和管理

webView.onResume() ;

webView.onPause();

Webview.goBack()

Webview.goForward()

WebViewClient类,处理各种通知,请求事件
shouldOverrideUrlLoading() 所有加载都经过这个方法,划重点,很重要。
onPageStarted()
onPageFinished()
onLoadResource() 每一个资源(比如图片)的加载都会调用一次。
WebChromeClient类.辅助 WebView 处理 Javascript 
onProgressChanged()用于显示加载进度
onReceivedTitle() 获取Web页中的标题 

二: 如何与JS代码进行交互

1 Android和JS代码通过WebView控件进行交互。

2 Android如何与JS交互?

1.1 通过WebViewloadUrl()

调用流程如下:
将需要调用的JS代码以.html格式放到src/main/assets文件夹里
在JS代码中声明供Android调用的方法。
在Android里通过WebView设置调用JS代码


WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/javascript.html");
//此处load的url即位放在本地的html文件
button.setOnClickListener(new View.OnClickListener(){
	public	void onClick(View v){
		mWebView.post(new Runnable(){
			public void run() {
			//此处要注意,方法名必须与.html中相同。
				mWebView.loadUrl("javascript:callJS()");
			}
		}
	}	
}


1.2 通过WebViewevaluateJavascript()

优点:该方法比第一种方法效率更高、使用更简洁。
代码如下:

mWebView.evaluateJavascript("javascript:callJS()",new ValueCallback<String>() {

	public void onReceiveValue(String value) {

		//处理js返回结果

	}
}


3 JS如何与Android交互?
3.1 WebViewaddJavascriptInterface()
实现步骤:

步骤1:定义一个与JS对象映射关系的Android类:AndroidtoJs

AndroidtoJs.java

// 继承自Object类
public class AndroidtoJs extends Object {

    // 定义JS需要调用的方法
    // 被JS调用的方法必须加入@JavascriptInterface注解
    @JavascriptInterface
    public void hello(String msg) {
        System.out.println("JS调用了Android的hello方法");
    }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

步骤2:将需要调用的JS代码以.html格式放到src/main/assets文件夹里

需要加载JS代码:javascript.html

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <title>Carson</title>  
      <script>


         function callAndroid(){
        // 由于对象映射,所以调用test对象等于调用Android映射的对象
            test.hello("js调用了android中的hello方法");
         }
      </script>
   </head>
   <body>
      //点击按钮则调用callAndroid函数
      <button type="button" id="button1" onclick="callAndroid()"></button>
   </body>
</html>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

步骤3:在Android里通过WebView设置Android类与JS代码的映射

详细请看注释

public class MainActivity extends AppCompatActivity {

    WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWebView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = mWebView.getSettings();

        // 设置与Js交互的权限
        webSettings.setJavaScriptEnabled(true);

        // 通过addJavascriptInterface()将Java对象映射到JS对象
        //参数1:Javascript对象名
        //参数2:Java对象名
        mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS类对象映射到js的test对象

        // 加载JS代码
        // 格式规定为:file:///android_asset/文件名.html
        mWebView.loadUrl("file:///android_asset/javascript.html");
3.2 通过 WebViewClient 的 shouldOverrideUrlLoading ()
实现步骤:
  • 具体原理: 

    1. Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url
    2. 解析该 url 的协议
    3. 如果检测到是预先约定好的协议,就调用相应方法 

    即JS需要调用Android的方法

  • 具体使用: 
    步骤1:在JS约定所需要的Url协议 
    JS代码:javascript.html

    以.html格式放到src/main/assets文件夹里

<!DOCTYPE html>
<html>

   <head>
      <meta charset="utf-8">
      <title>Carson_Ho</title>

     <script>
         function callAndroid(){
            /*约定的url协议为:js://webview?arg1=111&arg2=222*/
            document.location = "js://webview?arg1=111&arg2=222";
         }
      </script>
</head>

<!-- 点击按钮则调用callAndroid()方法  -->
   <body>
     <button type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
   </body>
</html>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

当该JS通过Android的mWebView.loadUrl("file:///android_asset/javascript.html")加载后,就会回调shouldOverrideUrlLoading (),接下来继续看步骤2:

步骤2:在Android通过WebViewClient复写shouldOverrideUrlLoading ()

MainActivity.java

public class MainActivity extends AppCompatActivity {

    WebView mWebView;
//    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWebView = (WebView) findViewById(R.id.webview);

        WebSettings webSettings = mWebView.getSettings();

        // 设置与Js交互的权限
        webSettings.setJavaScriptEnabled(true);
        // 设置允许JS弹窗
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

        // 步骤1:加载JS代码
        // 格式规定为:file:///android_asset/文件名.html
        mWebView.loadUrl("file:///android_asset/javascript.html");// 复写WebViewClient类的shouldOverrideUrlLoading方法
mWebView.setWebViewClient(new WebViewClient() {
                                      @Override
                                      public boolean shouldOverrideUrlLoading(WebView view, String url) {

                                          // 步骤2:根据协议的参数,判断是否是所需要的url
                                          // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
                                          //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)

                                          Uri uri = Uri.parse(url);                                 
                                          // 如果url的协议 = 预先约定的 js 协议
                                          // 就解析往下解析参数
                                          if ( uri.getScheme().equals("js")) {

                                              // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
                                              // 所以拦截url,下面JS开始调用Android需要的方法
                                              if (uri.getAuthority().equals("webview")) {

                                                 //  步骤3:
                                                  // 执行JS所需要调用的逻辑
                                                  System.out.println("js调用了Android的方法");
                                                  // 可以在协议上带有参数并传递到Android上
                                                  HashMap<String, String> params = new HashMap<>();
                                                  Set<String> collection = uri.getQueryParameterNames();

                                              }

                                              return true;
                                          }
                                          return super.shouldOverrideUrlLoading(view, url);
                                      }
                                  }
        );
   }

三: 实际开发中的坑:

1:在Android中调用JS代码的时候,webView.Post方法必须在子线程中进行开启。

2:预防addJavascriptInterface()漏洞
4.2以下系统使用@addJavascriptInterface注解

3:防止WebView内存泄漏
使用getApplicationContext
在Activity使用完毕之后记得销毁

4:记得添加网络权限

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值