您的位置:首页 > 移动开发

Android WebView无法返回上一页的问题。

2017-02-20 10:03 471 查看
最近在做WebView的开发,发现安卓的webview确实有好多坑。主要说一下WebView无法正常返回上一页的问题。

首先WebView的基本配置。

@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
if (keyCode == keyEvent.KEYCODE_BACK) {//监听返回键,如果可以后退就后退
if (webView.canGoBack()) {
webView.goBack();
return true;

}
}
return super.onKeyDown(keyCode, keyEvent);
}

@Override
protected 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的时候会无反应。

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

@Override
protected 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方法,注:谨慎使用

@Override
protected 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;//历史索引位置

@Override
protected 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));
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐