我有一个广泛使用WebView的应用程序。当此应用程序的用户没有Internet连接时,会出现“网页不可用”和其他各种文本的页面。有没有办法在我的WebView中不显示这个通用文本?我想提供自己的错误处理。
private final Activity activity = this;
private class MyWebViewClient extends WebViewClient
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// I need to do something like this:
activity.webView.wipeOutThePage();
activity.myCustomErrorHandling();
Toast.makeText(activity, description, Toast.LENGTH_LONG).show();
}
}
我发现WebView->clearView实际上并没有清除视图。
答案 0 :(得分:90)
首先在HTML中创建自己的错误页面并将其放在您的资源文件夹中,我们称之为myerrorpage.html 然后使用onReceivedError:
mWebView.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
mWebView.loadUrl("file:///android_asset/myerrorpage.html");
}
});
答案 1 :(得分:28)
我找到的最佳解决方案是在OnReceivedError事件中加载一个空页面,如下所示:
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
view.loadUrl("about:blank");
}
答案 2 :(得分:9)
最后,我解决了这个问题。 (它一直工作到现在..)
我的解决方案是这样的......
准备布局以显示错误发生的时间而不是网页(一个脏的'页面未找到的消息')布局有一个按钮," RELOAD"一些指导信息。
如果发生错误,请记住使用布尔值并显示我们准备的布局。
这是我的完整资料来源。看看这个。
public class MyWebViewActivity extends ActionBarActivity implements OnClickListener {
private final String TAG = MyWebViewActivity.class.getSimpleName();
private WebView mWebView = null;
private final String URL = "http://www.google.com";
private LinearLayout mlLayoutRequestError = null;
private Handler mhErrorLayoutHide = null;
private boolean mbErrorOccured = false;
private boolean mbReloadPressed = false;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
((Button) findViewById(R.id.btnRetry)).setOnClickListener(this);
mlLayoutRequestError = (LinearLayout) findViewById(R.id.lLayoutRequestError);
mhErrorLayoutHide = getErrorLayoutHideHandler();
mWebView = (WebView) findViewById(R.id.webviewMain);
mWebView.setWebViewClient(new MyWebViewClient());
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.setWebChromeClient(getChromeClient());
mWebView.loadUrl(URL);
}
@Override
public boolean onSupportNavigateUp() {
return super.onSupportNavigateUp();
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btnRetry) {
if (!mbErrorOccured) {
return;
}
mbReloadPressed = true;
mWebView.reload();
mbErrorOccured = false;
}
}
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
return;
}
else {
finish();
}
super.onBackPressed();
}
class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
if (mbErrorOccured == false && mbReloadPressed) {
hideErrorLayout();
mbReloadPressed = false;
}
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
mbErrorOccured = true;
showErrorLayout();
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
private WebChromeClient getChromeClient() {
final ProgressDialog progressDialog = new ProgressDialog(MyWebViewActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
return new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
};
}
private void showErrorLayout() {
mlLayoutRequestError.setVisibility(View.VISIBLE);
}
private void hideErrorLayout() {
mhErrorLayoutHide.sendEmptyMessageDelayed(10000, 200);
}
private Handler getErrorLayoutHideHandler() {
return new Handler() {
@Override
public void handleMessage(Message msg) {
mlLayoutRequestError.setVisibility(View.GONE);
super.handleMessage(msg);
}
};
}
}
另外:这是布局......
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rLayoutWithWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:id="@+id/webviewMain"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/lLayoutRequestError"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<Button
android:id="@+id/btnRetry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minWidth="120dp"
android:text="RELOAD"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
答案 3 :(得分:6)
查看Android WebView onReceivedError()处的讨论。这很长,但共识似乎是a)你无法阻止“网页不可用”页面出现,但b)你总是在得到onReceivedError之后加载一个空页
答案 4 :(得分:5)
当webview嵌入某个自定义视图中时,用户几乎认为他正在看到本机视图而不是webview,在这种情况下显示“无法加载页面”错误是荒谬的。在这种情况下我通常做的是加载空白页面并显示如下的祝酒消息
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
Log.e(TAG," Error occured while loading the web page at Url"+ failingUrl+"." +description);
view.loadUrl("about:blank");
Toast.makeText(App.getContext(), "Error occured, please check newtwork connectivity", Toast.LENGTH_SHORT).show();
super.onReceivedError(view, errorCode, description, failingUrl);
}
});
答案 5 :(得分:2)
您可以使用GET
请求获取页面内容,然后使用Webview
显示该数据,这样您就不会使用多个服务器调用。或者,您可以使用Javascript
检查DOM
对象的有效性。
答案 6 :(得分:2)
也许我误解了这个问题,但听起来你说你得到了错误收到回调,而你只是在问什么是不显示错误的最佳方法?为什么不从屏幕上删除网页视图和/或在其上显示另一个视图?
答案 7 :(得分:1)
我想如果你坚持这样做,你可以在调用loadURL函数之前检查资源是否存在。 只需简单地覆盖函数并在调用super()
之前进行检查备注(可能是偏离主题的):在http中,有一个名为HEAD的方法,描述如下:
HEAD方法与GET相同,只是服务器不能在响应中返回消息正文
这种方法可能很方便。 无论如何你实现它...检查这段代码:
import java.util.Map;
import android.content.Context;
import android.webkit.WebView;
public class WebViewPreLoad extends WebView{
public WebViewPreLoad(Context context) {
super(context);
}
public void loadUrl(String str){
if(//Check if exists)
super.loadUrl(str);
else
//handle error
}
public void loadUrl(String url, Map<String,String> extraHeaders){
if(//Check if exists)
super.loadUrl(url, extraHeaders);
else
//handle error
}
}
你可以尝试使用
进行检查if(url.openConnection().getContentLength() > 0)
答案 8 :(得分:1)
在这里,我找到了最简单的解决方案。看看这个..
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// view.loadUrl("about:blank");
mWebView.stopLoading();
if (!mUtils.isInterentConnection()) {
Toast.makeText(ReportingActivity.this, "Please Check Internet Connection!", Toast.LENGTH_SHORT).show();
}
super.onReceivedError(view, errorCode, description, failingUrl);
}
这是isInterentConnection()方法......
public boolean isInterentConnection() {
ConnectivityManager manager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (manager != null) {
NetworkInfo info[] = manager.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
答案 9 :(得分:0)
我只是将网页更改为您用于错误处理的任何内容:
getWindow().requestFeature(Window.FEATURE_PROGRESS);
webview.getSettings().setJavaScriptEnabled(true);
final Activity activity = this;
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
activity.setProgress(progress * 1000);
}
});
webview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String
failingUrl) {
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
});
webview.loadUrl("http://slashdot.org/");
这可以在http://developer.android.com/reference/android/webkit/WebView.html
上找到答案 10 :(得分:0)
我一直在努力解决今天放弃那些烦躁的Google错误页面的问题。可以使用上面的Android示例代码以及许多其他论坛(问我怎么知道):
wv.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
if (view.canGoBack()) {
view.goBack();
}
Toast.makeText(getBaseContext(), description, Toast.LENGTH_LONG).show();
}
}
});
如果你将shouldOverrideUrlLoading()作为另一个webclient放入。至少,这对我的2.3.6设备有用。我们稍后会看到它的工作原理。那我现在只会压抑我,我敢肯定。 goBack位是我的。你可能不想要它。
答案 11 :(得分:0)
试试这个
@SuppressWarnings("deprecation")
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Your handling
}
@Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
}
}
答案 12 :(得分:0)
我们可以将webView的可见性设置为0(view.INVISIBLE)并显示一些消息。 此代码适用于在lolipop上运行的应用程序。
@SuppressWarnings("deprecation")
@Override
public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) {
// hide webView content and show custom msg
webView.setVisibility(View.INVISIBLE);
Toast.makeText(NrumWebViewActivity.this,getString(R.string.server_not_responding), Toast.LENGTH_SHORT).show();
}
@TargetApi(android.os.Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
// Redirect to deprecated method, so you can use it in all SDK versions
onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
}
答案 13 :(得分:0)
我不得不面对这个问题,并试图从不同的角度来解决它。最后,我通过使用单个标志来检查是否发生了错误,从而找到了解决方案。
... extends WebViewClient {
boolean error;
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
showLoading(true);
super.onPageStarted(view, url, favicon);
error = false; // IMPORTANT
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(!error) {
Observable.timer(100, TimeUnit.MICROSECONDS, AndroidSchedulers.mainThread())
.subscribe((data) -> view.setVisibility(View.VISIBLE) );
}
showLoading(false);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
view.stopLoading();
view.setVisibility(View.INVISIBLE)
error = true;
// Handle the error
}
@Override
@TargetApi(android.os.Build.VERSION_CODES.M)
public void onReceivedError(WebView view,
WebResourceRequest request,
WebResourceError error) {
this.onReceivedError(view, error.getErrorCode(),
error.getDescription().toString(),
request.getUrl().toString());
}
}
这样我每次出现错误时都会隐藏页面,并在页面再次正确加载时显示。
还增加了一点延迟。
我避免了加载空白页面的解决方案,因为它不允许您稍后执行webview.reload(),因为它在导航历史记录中添加了新页面。
答案 14 :(得分:-1)
尝试此shouldOverrideUrlLoading,然后重定向到另一个网址,检查是否应该加载基于该网页的互联网连接。
答案 15 :(得分:-1)
覆盖您的WebViewClient方法
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
view.clearView();
}
view.loadUrl('about:blank')
有副作用,因为它会取消原始网址加载。