創建webview
// 這個不用說
this.getSettings().setJavaScriptEnabled(true);
// 這個解決跨域的問題
this.getSettings().setAllowFileAccessFromFileURLs(true);
this.setWebViewClient(new MyWebViewClient());
this.setWebChromeClient(new MyWebChromeClient());
// 這個是js調用Android方法的聲明,第一個參數是類對象(也就是放Android哪個方法要被js調用的類,第二個參數可以自定義)
this.addJavascriptInterface(map.getCallback(), "Android");
開發過程中,這個onConsoleMessage這個很重要,監聽js中的console.log的打印信息,因爲無法debug
class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// 監聽js的alert打印 警告消息框
FMLog.li("alert---" + url + message + result.toString());
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
JsPromptResult result) {
// 輸入消息框
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
// 確認消息框
return true;
}
@RequiresApi(api = Build.VERSION_CODES.FROYO)
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
// 監聽console打印
ConsoleMessage.MessageLevel messageLevel = consoleMessage.messageLevel();
if (messageLevel == ConsoleMessage.MessageLevel.ERROR) {
FMLog.le("error", "linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message());
} else if (messageLevel == ConsoleMessage.MessageLevel.LOG) {
FMLog.li("console---" + "linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";level:" + consoleMessage.messageLevel());
} else if (messageLevel == ConsoleMessage.MessageLevel.WARNING) {
FMLog.lw("FMMapSdk_waring:",
"linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";" +
"level:" + consoleMessage.messageLevel());
} else {
FMLog.li("linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";" +
"level:" + consoleMessage.messageLevel());
}
return true;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
FMLog.li("pro---" + newProgress + "");
}
}
html中的js方法,一定是要在onPageFinished這個回調之後纔可以調用,否則會報錯!!!
html中的js方法,一定是要在onPageFinished這個回調之後纔可以調用,否則會報錯!!!
html中的js方法,一定是要在onPageFinished這個回調之後纔可以調用,否則會報錯!!!
。
。
。無數遍
onReceivedError可以監聽你方法調用錯誤的log打印
class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
FMLog.li("url---" + url);
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
loadMap(map.getFMLoadOption());
FMLog.li("onPageFinished---" + "加載完成");
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
FMLog.li("onPageStarted---" + "開始加載");
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
FMLog.li("onReceivedError---" + request.getUrl().toString() + "--error:" + error);
} else {
FMLog.li("onReceivedError---" + "--error:" + view.getUrl());
}
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
FMLog.li("onReceivedError---" + "errorCode:" + errorCode + "description:" + description + "failingUrl:" + failingUrl);
}
}
Android 調用 js
兩個方式
this.evaluateJavascript("javascript:method()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});
this.loadUrl("javascript:" + "loadMap('" + option + "')");
第一個是Android5.0之後使用,帶返回值,但是這個不是同步返回;
第二個不帶返回值,參數一版用一個json.toString();方便傳遞更多的參數
這樣就可以封裝通用的方式進行調用
/**
* 通用方法
*
* @param method 方法名
* @param object 參數
*/
private void jsMethod(String method, Object object) {
this.mView.loadUrl(mView.JSMethodHead + "" + method + "(" + object + ")");
}
private void jsMethod(String method) {
this.mView.loadUrl(mView.JSMethodHead + "" + method + "()");
}
private void jsMethodCallBack(final String method, Object object, final FMJsMethodListener listener) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.mView.evaluateJavascript(mView.JSMethodHead + method + "(" + object + ")",
new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
listener.recive(method, value);
}
});
}
}
private void jsMethodCallBack(final String method, final FMJsMethodListener listener) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.mView.evaluateJavascript(mView.JSMethodHead + method + "()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
listener.recive(method, value);
}
});
}
}
js 調用 Android
Android這邊聲明的類在初始化那已經說過了,創建一個類
class FMMapCallBack {
private final Handler handler;
FMMapCallBack(Handler handler) {
this.handler = handler;
}
@JavascriptInterface
public void loadSuccess(String json) {
Message message = handler.obtainMessage();
message.what = 1;
message.obj = json;
handler.sendMessage(message);
}
@JavascriptInterface
public void loadFailed(String error) {
Message message = handler.obtainMessage();
message.what = 0;
message.obj = error;
handler.sendMessage(message);
}
@JavascriptInterface
public void JsCallBack(String json){
try {
JSONObject obj = new JSONObject(json);
String name = obj.getString("name");
Object value = obj.get("value");
switch (name) {
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
js 這邊可以通過初始化的自定義關鍵字進行調用
window.Android.loadSuccess(JSON.stringify(json));
你發現我再callback類中使用了handler,那是因爲js調用Android不是同步,回調方法執行在js thread線程中