最近在做WebView的开发,发现安卓的webview确实有好多坑。主要说一下WebView无法正常返回上一页的问题。

首先WebView的基本配置。

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent keyEvent) {        if (keyCode == keyEvent.KEYCODE_BACK) {//监听返回键,如果可以后退就后退            if (webView.canGoBack()) {                    webView.goBack();                    return true;                            }        }        return super.onKeyDown(keyCode, keyEvent);}@Overrideprotected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);    setContentView(...)    WebView webview = findViewById...;    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);//支持js      webSettings.setDomStorageEnabled(true);//支持DOM API }

AndroidManifest.xml添加权限

<?xml version="1.0" encoding="utf-8"?> 

然后发现出现了一些html中的页面中部分返回键无法返回,js中的代码是history.back();检查webview的url,发现当url的前缀从https的域名跳转http的时候会无反应。

一方面可以增加如下配置。

@Overrideprotected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);    setContentView(...)    WebView webview = findViewById...;    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);//支持js    webSettings.setDomStorageEnabled(true);//支持DOM API     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {        //设置当一个安全站点企图加载来自一个不安全站点资源时WebView的行为,        //在这种模式下,WebView将允许一个安全的起源从其他来源加载内容,即使那是不安全的.        //如果app需要安全性比较高,不应该设置此模式        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//解决app中部分页面非https导致的问题    }        webView.setWebViewClient(new WebViewClient() {                                                    @Override                            public boolean shouldOverrideUrlLoading(WebView view, String url) {                                // TODO Auto-generated method stub                                // return false;//可以解决由于重定向导致的webview.goback()无法返回的问题                                view.loadUrl(url);                                return true;                            }                            @Override                            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {                                Log.e(TAG, "onReceivedSslError");                                handler.proceed();// 接受所有网站的证书                                //super.onReceivedSslError(view, handler, error);                            }                        });}


如果发现还有问题还可以尝试重写JS方法,注:谨慎使用

@Overrideprotected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);    setContentView(...)    WebView webview = findViewById...;    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);//支持js    webSettings.setDomStorageEnabled(true);//支持DOM API     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {        //设置当一个安全站点企图加载来自一个不安全站点资源时WebView的行为,        //在这种模式下,WebView将允许一个安全的起源从其他来源加载内容,即使那是不安全的.        //如果app需要安全性比较高,不应该设置此模式        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//解决app中部分页面非https导致的问题    }        webView.setWebViewClient(new WebViewClient() {                                                    @Override                            public boolean shouldOverrideUrlLoading(WebView view, String url) {                                // TODO Auto-generated method stub                                // return false;//可以解决由于重定向导致的webview.goback()无法返回的问题                                view.loadUrl(url);                                return true;                            }                            @Override                            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {                                Log.e(TAG, "onReceivedSslError");                                handler.proceed();// 接受所有网站的证书                                //super.onReceivedSslError(view, handler, error);                            }                        });    webView.addJavascriptInterface(new JsObject(webView), "history");//重写了webview中的js方法}class JsObject {    private static final String TAG ="JsObject" ;    private WebView JsObjectwebView;    public JsObject(WebView webView) {        JsObjectwebView = webView;    }    @JavascriptInterface    public void back() {        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                Log.i(TAG, "goBack:");                JsObjectwebView.goBack();            }        });    }    @JavascriptInterface    public void forward() {        Log.i(TAG, "forward:");        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                JsObjectwebView.goForward();            }        });    }    @JavascriptInterface    public void go(final String i) {        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                JsObjectwebView.goBackOrForward(Integer.parseInt(i));            }        });    }}

但是即便如此,在部分android5.1系统(oppor9,oppor9s等)仍然存在不能正常返回的问题。所以需要自己去查询history队列,然后loadURL

private int androidVersion;//系统版本private int listSize;//历史长度private int historyPostion;//历史索引位置@Overrideprotected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);    setContentView(...)    WebView webview = findViewById...;    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);//支持js    webSettings.setDomStorageEnabled(true);//支持DOM API     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {        //设置当一个安全站点企图加载来自一个不安全站点资源时WebView的行为,        //在这种模式下,WebView将允许一个安全的起源从其他来源加载内容,即使那是不安全的.        //如果app需要安全性比较高,不应该设置此模式        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//解决app中部分页面非https导致的问题    }        webView.setWebViewClient(new WebViewClient() {                            @Override                            public void onFormResubmission(WebView view, Message dontResend, Message resend) {                                resend.sendToTarget();                            }                                                    @Override                            public boolean shouldOverrideUrlLoading(WebView view, String url) {                                // TODO Auto-generated method stub                                // return false;//可以解决由于重定向导致的webview.goback()无法返回的问题                                                                if (androidVersion == 22) {//安卓5.1webview.goback()无法正常返回。                                    WebBackForwardList list = webView.copyBackForwardList();//webView队列                                    listSize = list.getSize();                                    historyPostion = listSize;                                }                                view.loadUrl(url);                                return true;                            }                            @Override                            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {                                Log.e(TAG, "onReceivedSslError");                                handler.proceed();// 接受所有网站的证书                                //super.onReceivedSslError(view, handler, error);                            }                        });    webView.addJavascriptInterface(new JsObject(webView), "history");//重写了webview中的js方法}@Override public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {        if (keyCode == keyEvent.KEYCODE_BACK) {//监听返回键,如果可以后退就后退           if (webView.canGoBack()) {                if (androidVersion == 22) {//部分android5.1 webview存在问题,需要自己查找历史记录并loadUrl                    WebBackForwardList list = webView.copyBackForwardList();                    historyPostion--;                    String url = list.getItemAtIndex(historyPostion).getUrl();                    webView.loadUrl(url);                } else {                    webView.goBack();                }                return true;            }        }        return super.onKeyDown(keyCode, keyEvent);    }class JsObject {    private static final String TAG ="JsObject" ;    private WebView JsObjectwebView;    public JsObject(WebView webView) {        JsObjectwebView = webView;    }    @JavascriptInterface    public void back() {        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                Log.i(TAG, "goBack:");                JsObjectwebView.goBack();            }        });    }    @JavascriptInterface    public void forward() {        Log.i(TAG, "forward:");        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                JsObjectwebView.goForward();            }        });    }    @JavascriptInterface    public void go(final String i) {        JsObjectwebView.post(new Runnable() {            @Override            public void run() {                JsObjectwebView.goBackOrForward(Integer.parseInt(i));            }        });    }}

更多相关文章

  1. 安全新手入坑——HTML标签
  2. Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
  3. activity属性,加载模式等
  4. Android(安卓)向右滑动关闭页面
  5. Android(安卓)Studio 统计代码行数插件 — Statistic
  6. android webview网页控件
  7. Android实现ListView异步加载图片总结
  8. Android(安卓)音乐裁剪器
  9. PreferenceFragment详解

随机推荐

  1. Android环境变量作用--命令行操作(ADB、AV
  2. android 串口通信选择
  3. Android/OPhone开发完全讲义
  4. Android使用Application总结
  5. Android(安卓)自定义视图
  6. Mac下关于The "android" command is depr
  7. ArcGIS API For Android离线地图的实现
  8. Android中RecyclerView Adapter的骚操作
  9. 睡眠唤醒机制简介
  10. 《Android和PHP最佳实践》官方站