[英]Prevent WebView from displaying “web page not available”
我有一個廣泛使用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實際上並沒有清除視圖。
首先用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");
}
});
我找到的最佳解決方案是在OnReceivedError事件中加載一個空頁面,如下所示:
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
view.loadUrl("about:blank");
}
最后,我解決了這個問題。 (它一直工作到現在..)
我的解決方案是這樣的......
准備布局以顯示何時發生錯誤而不是網頁(臟頁'未找到消息')布局有一個按鈕,“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>
查看Android WebView onReceivedError()上的討論。 這很長,但共識似乎是a)你無法阻止“網頁不可用”頁面出現,但b)你總是在得到onReceivedError之后加載一個空頁面
當webview嵌入某些自定義視圖中時,用戶幾乎認為他正在看到本機視圖而不是webview,在這種情況下顯示“頁面無法加載”錯誤是荒謬的。 在這種情況下我通常做的是加載空白頁面並顯示如下的Toast消息
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);
}
});
您可以使用GET
請求獲取頁面內容,然后使用Webview
顯示該數據,這樣您就不會使用多個服務器調用。 另外,您可以使用Javascript
檢查DOM
對象的有效性。
也許我誤解了這個問題,但聽起來你說你得到了錯誤收到的回調,而你只是在問什么是不顯示錯誤的最佳方法? 為什么不從屏幕上刪除Web視圖和/或在其上顯示另一個視圖?
在這里,我找到了最簡單的解決方案 看看這個..
@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;
}
我想如果你堅持這樣做,你可以在調用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)
我一直在努力解決今天放棄那些煩躁的谷歌錯誤頁面的問題。 可以使用上面的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位是我的。 你可能不想要它。
試試這個
@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());
}
}
我們可以將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());
}
我不得不面對這個問題,並試圖從不同的角度來解決它。 最后,我通過使用單個標志來檢查是否發生了錯誤,從而找到了解決方案。
... 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(),因為它在導航歷史記錄中添加了新頁面。
我只是將網頁更改為您用於錯誤處理的任何內容:
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上找到
覆蓋您的WebViewClient方法
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
view.clearView();
}
view.loadUrl('about:blank')
有副作用,因為它取消了原始的URL加載。
嘗試這個shouldOverrideUrlLoading ,然后重定向到另一個url檢查是否應該加載基於該頁面的互聯網conncetion 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.