
正文
一切基于項(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;
}
});