android原生webview中呼叫JS方法並傳遞引數給JS遇到的問題
在使用webview時,需要給JS傳遞一個引數,之前前端同事把JS方法內容和html內容分離了,所以在使用下面的方法的時候一直顯示方法未定義[INFO:CONSOLE(1)] "Uncaught ReferenceError: load is not defined", source: (1),後來把JS方法寫到html裡,這個方法就可以呼叫了,因為是第一次做這個問題,所以不知道有沒有直接呼叫單獨JS檔案裡的方法
webview不能夠正常載入JS的問題可以看我的另一篇文章 http://blog.csdn.net/weixue9/article/details/78324737,呼叫Js方法並傳遞引數的具體步驟如下:
通過 WebViewClient 的方法shouldOverrideUrlLoading ()回撥攔截 url
具體原理:
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>
當該JS通過Android的mWebView.loadUrl("file:///android_asset/javascript.html")載入後,就會回撥shouldOverrideUrlLoading (),接下來繼續看步驟2:
步驟2:在Android通過WebViewClient複寫shouldOverrideUrlLoading()
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);
// 設定允許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);
}
}
特點
優點:不存在JS程式碼呼叫一定要在 onPageFinished() 回撥之後才能呼叫,否則不會呼叫。;
缺點:JS獲取Android方法的返回值複雜。如果JS想要得到Android方法的返回值,只能通過WebView的loadUrl()去執行JS方法把返回值傳遞回去,相關的程式碼如下:
// Android:MainActivity.java
mWebView.loadUrl("javascript:returnResult(" + result + ")");
// JS:javascript.html
function returnResult(result){
alert("result is" + result);
}
上面的方法是借鑑http://www.jianshu.com/p/345f4d8a5cfa的方法