现在有一些App应用采用android自带的WebView控件,加载Html5实现混合开发。大家在开发中肯定遇到过很多坑,打算把一些问题进行一下总结,如下:
- 怎么实现java调用js?
- Android4.2下 WebView的addJavascriptInterface漏洞解决方案?
- Android4.4 支持文件上传?
- WebView怎么实现下拉回弹效果?
- WebView怎么实现cookie管理?
所有的解决方法源码WebViewH5Mutual
第一个问题
对于Android调用JS代码的方法有2种:
(1)通过WebView的loadUrl()
(2)通过WebView的evaluateJavascript()
evaluateJavascript方法是在android 4.4后才提供的方法,效率更高。执行过程不会使页面刷新,而loadUrl会刷新界面。
解决方法
两种方法混合使用,即Android 4.4以下使用loadUrl方法,Android 4.4以上使用evaluateJavascript方法。
public void callJs(String js, final ValueCallback<String> callback) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.evaluateJavascript(js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
if (callback != null)
callback.onReceiveValue(value);
}
});
} else {
mWebView.loadUrl(js);
}
}
第二个问题
第三个问题
通过重写WebChromeClient中的openFileChooser()方法。
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
LogUtils.i(TAG, "openFileChooser>=5.0");
if (AgentWebUtils.isOverriedMethod(mWebChromeClient, "onShowFileChooser", ChromePath + ".onShowFileChooser", WebView.class, ValueCallback.class, FileChooserParams.class)) {
return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
webview.setWebChromeClient(new WebChromeClient() {
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
***
}
// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
***
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback,
String acceptType, String capture) {
***
}
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
***
return true;
}
});
第四个问题
第五个问题
通过CookieManager将cookie同步到WebView中。如果API是21以下的话,需要在CookieManager前调用CookieSyncManager.createInstance(context)方法。
public static boolean syncCookie(Context context, String url, String cookie) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(context);
}
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(url, cookie);//如果没有特殊需求,这里只需要将session id以"key=value"形式作为cookie即可
String newCookie = cookieManager.getCookie(url);
return TextUtils.isEmpty(newCookie)?false:true;
}