首先wenview大家都知道的一些API
WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 :
onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
- WebView 文件上传,直接看代码:
webView.setWebChromeClient(new MyWebChromeClient());
private ValueCallback<Uri[]> mUploadCallbackAboveL;
private ValueCallback<Uri> mUploadMessage;
private class MyWebChromeClient extends WebChromeClient {
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
if (mUploadMessage != null) return;
mUploadMessage = uploadMsg;
showPhotoView();
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
// For Android 5.0+
public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
if (mUploadCallbackAboveL != null){
return false;
}
mUploadCallbackAboveL = filePathCallback;
showPhotoView();
return true;
}
}
/**
* 自定义的文件选择框,包括相机 图库
*/
private void showPhotoView() {
photoSelectFragment = new PhotoSelectFragment();
photoSelectFragment.setOnPhotoListItemClickListener(this);
photoSelectFragment.setOnDismissListener(this);
photoSelectFragment.show(getSupportFragmentManager(),
"photoSelectFragment");
}
当文件选择的dialog消失时或者取消时要调用以下代码,否则就会出现再次点击不再弹出选择dialog:
/**
* 重置 mUploadMessage
*/
private void clearUploadCallBack(){
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {//5.0以下
if (mUploadMessage != null){
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
}
}else {
if(mUploadCallbackAboveL != null){
mUploadCallbackAboveL.onReceiveValue(null);
mUploadCallbackAboveL = null;
}
}
}
2.WebView 图片延迟加载:
有些页面如果包含网络图片,在移动设备上我们等待加载图片的时间可能会很长,所以我们需要让图片延时加载,这样不影响我们加载页面的速度,同样代码说话:
定义变量:
boolean blockLoadingNetworkImage=false;
在WebView初始化的时候设置,就是这么简单就可以了:
blockLoadingNetworkImage = true;
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!blockLoadingNetworkImage){
webView.getSettings().setBlockNetworkImage(true);
}
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (blockLoadingNetworkImage){
webView.getSettings().setBlockNetworkImage(false);
}
}
});
3.JS调用native:
js调用原生大概有两种方法
1.截取url,获取指定的url,例如页面上有个拨打电话的调用,我们就可以在wenview中这样截取:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
Log.e("zhaogl", url);
if (url.startsWith("tel:")){//拨打电话
String[] ss = url.split(":");
if (ss.length > 1 && ss[1] != null){
CommonUtil.call(WebViewActivity.this,ss[1]);
}
}else if (url.equalsIgnoreCase("http://www.baidu.com/")){
WebViewActivity.this.finish();
}else {
view.loadUrl(url);
}
return true;
}
});
2.调用Java写好的方法:
首先我们要定义一个方法给js调用,这里我把这个方法封装到一个类中:
public class InJavaScript {
private static InJavaScript instance;
public InJavaScript() {
}
public static InJavaScript getInstance() {
if (instance == null){
instance = new InJavaScript();
}
return instance;
}
/**
* 分享
* @param str 内容
* @param targetUrl url
*/
@JavascriptInterface
public void runOnAndroidShare(String str,String targetUrl) {
WebViewEvent event = new WebViewEvent();
event.isShare = true;
event.content = str;
event.url = targetUrl;
EventBus.getDefault().post(event);
}
/**
* 关闭 window.close 不起作用,代替之
*/
@JavascriptInterface
public void closeWindowForAndroid(){
WebViewEvent event = new WebViewEvent();
event.isCloseWindow = true;
EventBus.getDefault().post(event);
}
}
写好的java类及方法如果想让js调用,还需要有如下设置:
webView.addJavascriptInterface(InJavaScript.getInstance(), "injs");
js中就可以用以下方式调用:
function sendToAndroid(){
window.injs.runOnAndroidShare(str,str);//调用android的函数
}
注意,第二中方法在4.2以下版本存在js安全漏洞,但是目前市场上的安卓大部分都已经在4.2以上了,所以如果你的项目安全要求不是那么高,可以正常使用。现在有很多第三方的框架解决这个问题,大家可以去自己查找。
3.处理返回按键:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
if (photoSelectFragment != null){
photoSelectFragment.dismiss();
clearUploadCallBack();
}
webView.goBack();// 返回前一个页面
return true;
}
return super.onKeyDown(keyCode, event);
}
整理出来的源码
源码下载