Android WebView與JS交互實(shí)例

與js交互示例.jpg

正文

一切基于項(xiàng)目WebViewStudy來(lái)說(shuō)明,都是最小單元案例,可作為參考研究,本文從幾個(gè)方面來(lái)講解:

  • 1、Java調(diào)用WebView里的js代碼(傳遞參數(shù))
  • 2、WebView里的js代碼調(diào)用Java本地方法(傳遞參數(shù))
  • 3、外部注入js代碼
  • 4、WebView長(zhǎng)按事件

相關(guān)JS代碼:

<html>
<head>
    <title>js調(diào)用android原生代碼</title>
    <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
    <meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
    <script type="text/javascript">
        function javacalljs(){
             document.getElementById("content").innerHTML +=
                 "<br\>java調(diào)用了js函數(shù),無(wú)參";
        }

        <!--這里取到的是 android端傳過(guò)來(lái)的數(shù)據(jù)-->
        function javacalljswithargs(data){
             document.getElementById("content").innerHTML +=
                 ("<br\>"+data);
        }

    </script>
</head>
<body>
    <br/><br/>
    <li><a onClick="window.injectedObject.startFunction()">點(diǎn)擊調(diào)用java代碼</a></li>
    <!--可以將android端傳過(guò)來(lái)的數(shù)據(jù),處理后,放在這里再傳給android端-->
    <li><a onClick="window.injectedObject.startFunction('我是網(wǎng)頁(yè)傳出來(lái)的數(shù)據(jù)')">點(diǎn)擊調(diào)用java代碼并傳遞參數(shù)</a></li><br/>
<div id="content">內(nèi)容顯示</div>
</body>
</html>

Java調(diào)用WebView里的js代碼(傳遞參數(shù))

// 告訴WebView啟用JavaScript執(zhí)行。默認(rèn)的是false。
ws.setJavaScriptEnabled(true);
1、如果點(diǎn)擊調(diào)用就直接執(zhí)行就好:

// 無(wú)參數(shù)調(diào)用
webView.loadUrl("javascript:javacalljs()");
// 傳遞參數(shù)調(diào)用
webView.loadUrl("javascript:javacalljswithargs('" + "android傳入到網(wǎng)頁(yè)里的數(shù)據(jù),有參" + "')");

2、如果是顯示后就調(diào)用,注意放在html顯示完成之后
MyWebViewClient.java

@Override
    public void onPageFinished(WebView view, String url) {
        // 無(wú)參數(shù)調(diào)用
        webView.loadUrl("javascript:javacalljs()");
        // 傳遞參數(shù)調(diào)用
        webView.loadUrl("javascript:javacalljswithargs('" + "android傳入到網(wǎng)頁(yè)里的數(shù)據(jù),有參" + "')");
        super.onPageFinished(view, url);
    }
    /**
     * 4.4以上可用 evaluateJavascript 效率高
     */
    private void load(String jsCode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            evaluateJavascript(jsCode, null);
        } else {
            loadUrl(jsCode);
        }
    }

WebView里的js代碼調(diào)用Java本地方法(傳遞參數(shù))

這里有一個(gè)js點(diǎn)擊方法:

<li><a onClick="window.injectedObject.startFunction()">點(diǎn)擊調(diào)用java代碼</a></li>
<li><a onClick="window.injectedObject.startFunction('我是網(wǎng)頁(yè)傳出來(lái)的數(shù)據(jù)')">點(diǎn)擊調(diào)用java代碼并傳遞參數(shù)</a></li>

實(shí)現(xiàn)與js交互接口:

webView.addJavascriptInterface(new MyJavascriptInterface(this), "injectedObject");

這里的"injectedObject"對(duì)應(yīng)js里的"window.injectedObject.startFunction()",其中MyJavascriptInterface.java:

/**
 * Created by jingbin on 2016/11/17.
 * js通信接口
 */
public class MyJavascriptInterface {
    private Context context;

    public MyJavascriptInterface(Context context) {
        this.context = context;
    }

    /**
     * 前端代碼嵌入js:
     * imageClick 名應(yīng)和js函數(shù)方法名一致
     *
     * @param src 圖片的鏈接
     */
    @JavascriptInterface
    public void imageClick(String src) {
        Log.e("imageClick", "----點(diǎn)擊了圖片");
        Log.e("src", src);
    }

    /**
     * 前端代碼嵌入js
     * 遍歷<li>節(jié)點(diǎn)
     *
     * @param type    <li>節(jié)點(diǎn)下type屬性的值
     * @param item_pk item_pk屬性的值
     */
    @JavascriptInterface
    public void textClick(String type, String item_pk) {
        if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(item_pk)) {
            Log.e("textClick", "----點(diǎn)擊了文字");
            Log.e("type", type);
            Log.e("item_pk", item_pk);
        }
    }

    /**
     * 網(wǎng)頁(yè)使用的js,方法無(wú)參數(shù)
     */
    @JavascriptInterface
    public void startFunction() {
        Log.e("startFunction", "----無(wú)參");
    }

    /**
     * 網(wǎng)頁(yè)使用的js,方法有參數(shù),且參數(shù)名為data
     *
     * @param data 網(wǎng)頁(yè)js里的參數(shù)名
     */
    @JavascriptInterface
    public void startFunction(String data) {
        Log.e("startFunction", "----有參" + data);
    }
}

且對(duì)標(biāo)里面的兩個(gè)方法:

    /**
     * 網(wǎng)頁(yè)使用的js,方法無(wú)參數(shù)
     */
    @JavascriptInterface
    public void startFunction() {
        Log.e("startFunction", "----無(wú)參");
    }

    /**
     * 網(wǎng)頁(yè)使用的js,方法有參數(shù),且參數(shù)名為data
     *
     * @param data 網(wǎng)頁(yè)js里的參數(shù)名
     */
    @JavascriptInterface
    public void startFunction(String data) {
        Log.e("startFunction", "----有參" + data);
    }

外部注入js代碼

有時(shí)候我們得到一個(gè)網(wǎng)頁(yè),這個(gè)網(wǎng)頁(yè)并不是我們訂制的,里面沒(méi)有我們調(diào)用的js代碼,這時(shí)候我們可在前端直接注入js的。
比如 網(wǎng)頁(yè)里面有圖片,我們點(diǎn)擊圖片想要查看圖片和保存圖片到本地,這時(shí)候網(wǎng)頁(yè)并沒(méi)有實(shí)現(xiàn)這個(gè)js方法供我們調(diào)用,但是我們可以注入js代碼,來(lái)實(shí)現(xiàn)這個(gè)需求。

在html加載完成之后,我們調(diào)用這段js:

// 這段js函數(shù)的功能就是,遍歷所有的img節(jié)點(diǎn),并添加onclick函數(shù),函數(shù)的功能是在圖片點(diǎn)擊的時(shí)候調(diào)用本地java接口并傳遞url過(guò)去
webView.loadUrl("javascript:(function(){" +
        "var objs = document.getElementsByTagName(\"img\");" +
        "for(var i=0;i<objs.length;i++)" +
        "{" +
        "objs[i].onclick=function(){window.injectedObject.imageClick(this.getAttribute(\"src\"));}" +
        "}" +
        "})()");

這時(shí)候再看MyJavascriptInterface.java里的imageClick方法:

    /**
     * 前端代碼嵌入js:
     * imageClick 名應(yīng)和js函數(shù)方法名一致
     *
     * @param src 圖片的鏈接
     */
    @JavascriptInterface
    public void imageClick(String src) {
        Log.e("imageClick", "----點(diǎn)擊了圖片");
        Log.e("src", src);
    }

src即為圖片鏈接,可以作為顯示和下載用。

WebView長(zhǎng)按事件

webView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        final WebView.HitTestResult hitTestResult = webView.getHitTestResult();
        // 如果是圖片類型或者是帶有圖片鏈接的類型
        if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
                hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
            // 彈出保存圖片的對(duì)話框
            new AlertDialog.Builder(WebViewActivity.this)
                    .setItems(new String[]{"查看大圖", "保存圖片到相冊(cè)"}, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String picUrl = hitTestResult.getExtra();
                            //獲取圖片
                            Log.e("picUrl", picUrl);
                            switch (which) {
                                case 0:
                                    break;
                                case 1:
                                    break;
                                default:
                                    break;
                            }
                        }
                    })
                    .show();
            return true;
        }
        return false;
    }
});

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容