Android WebView 踩过的坑

首先wenview大家都知道的一些API
这里写图片描述
这里写图片描述

WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 :

onCloseWindow(关闭WebView)   

onCreateWindow()   

onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)   

onJsPrompt   

onJsConfirm   

onProgressChanged   

onReceivedIcon   

onReceivedTitle 
  1. 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);
    }

整理出来的源码
源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值