关闭

如何实现WebView和js页面的交互

5278人阅读 评论(1) 收藏 举报
分类:

WebView默认是不支持js的,要支持js,必须要添加如下设置:

   WebSettings settings = webView.getSettings();
   settings.setJavaScriptEnabled(true);

1.如何实现js页面通过WebView调用Android app写好的代码呢?

通过webView.addJavascriptInterface(Object, "name");方法可以实现,其中参数Object表示的是需要与js交互的Java代码所在的类的类名,而参数name则表示js页面用来调用Java代码时的别名.简单来说就是将Java对象和Js对象进行绑定,通过别名可以找到与之关联的Java对象.例如:

webView.addJavascriptInterface(this, "callByJs");

其中this代表当前类,那么js就可以通过callByJs这个别名来调用与之关联的这个类的某些方法了,为什么说是某些方法呢?而不是所有的方法呢?

因为安全问题,在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有 @JavascriptInterface注解的Java函数。

例如:

 @JavascriptInterface
    public void setValue(String content) {
        Toast.makeText(TextCallJsActivity.this, "接收到的数据:"+content, Toast.LENGTH_SHORT).show();
    }
这样,js要调用Android代码中的setValue方法的时候,就可以通过如下方式调用了.

javascript:window.callByJs.setValue("hello android!!");


2.如何实现Android app 通过WebView调用js代码呢?

通过WebView的loadUrl方法可以实现.在loadUrl方法中写入要执行的js代码.例如:

webView.loadUrl("javascript:alert('hello js')");
上面只是调用js的alert函数而已,弹出一个提示框显示hello js.当然如果调用其他函数也是可以的.

符合格式:javascript:函数名(有参数/无参数)即可.

除此之外,loadUrl传入的js函数还可以写的更加复杂一些,例如:

webView.loadUrl("javascript:window.GETHTML.getHtml(document.getElementsByTagName('html')[0].innerHTML);");

分别解释下:

1.javascript:window.GETHTML.getHtml();

这句话表示的是js页面通过GETHTML别名调用Java的getHtml()方法.

2.document.getElementsByTagName('html')[0].innerHTML

这句话表示执行js的函数,通过document对象查找html标签内的html代码.

这一点可以符合一些特殊需求,例如在通过webView显示终端页的同时,还需要获取终端页的html代码中的某些元数据;有一种做法就是通过写一个http get请求去抓取html代码的.但是这样的话就相当于请求了当前页面2次了.另一种方法就是这里所说的通过调用js函数来实现,通常做法是在webView设置WebViewClient对象后,重写其onPageFinish方法,在onPageFinish方法内通过loadUrl方法来调用js代码获取html代码;


好了,以上说了那么多,来看个具体的例子吧.

这个Demo是这样的.WebView显示js页面,通过点击js页面的某个图片,会调用Java代码的某个方法,然后在这个方法的内部再调用js函数,js函数执行,然后替换当前显示的图片.

html页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <script type="text/javascript">
        //由java调用此方法
        var count = 0;
        function wave(){
            if(count %2 == 0){
                document.getElementById("droid").src="ic_launcher.png";
            }else{
                document.getElementById("droid").src="app_icon.png";
            }
            count ++;
        }
    </script>

</head>
<body>
    <a onclick="window.callByJs.clickOnAndroid()">
        <img id="droid" src="app_icon.png" mce_src="app_icon.png"/></br>Click me change icon!
    </a>
</body>

</html>

Android 代码:

package com.example.chenys.webviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;

/**
 * Created by mChenys on 2015/11/19.
 * 实现js页面调用android的方法,及android的方法里面再调用js页面的js函数,实现互调的过程.
 */
public class TextCallJsActivity2 extends Activity {
    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_call_js);
        final WebView webView = (WebView) findViewById(R.id.webView);
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new Object() {

            @JavascriptInterface
            public void clickOnAndroid() {
                System.out.println("clickOnAndroid被调用了....");
                /**
                 * 注意:这里调用webview的方法必须在同一个线程中完成,否则抛出异常:
                 * java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.
                 * (Expected Looper Looper (main, tid 1) {1d832dfa} called on Looper (JavaBridge, tid 263) {2a93b47f}, FYI main Looper is Looper (main, tid 1) {1d832dfa})
                 */
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        webView.loadUrl("javascript:wave()");
                    }
                });
            }
        }, "callByJs");
        webView.loadUrl("file:///android_asset/index2.html");
    }
}

效果图:


点击后变成:


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:153556次
    • 积分:2376
    • 等级:
    • 排名:第15682名
    • 原创:89篇
    • 转载:2篇
    • 译文:0篇
    • 评论:55条
    文章分类
    最新评论