У меня есть приложение, в котором широко используется WebView. Когда у пользователя этого приложения нет подключения к Интернету, появляется страница с надписью «веб-страница недоступна» и другой различный текст. Есть ли способ не отображать этот общий текст в моем 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"); } });
источник
view.loadUrl("about:blank");
перед loadUrl, чтобы предотвратить отображение страницы с ошибкой в течение доли секунды.Лучшее решение, которое я нашел, - загрузить пустую страницу в событии OnReceivedError следующим образом:
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); view.loadUrl("about:blank"); }
источник
view.loadUrl(noConnectionUrl);
дважды (где noConnectionUrl - это локальный файл с сообщением об ошибке). Это также помогло не «видеть» встроенную страницу с ошибкой в течение доли секунды.webView.goBack()
убедитесь, что обработали условие для этой пустой страницы. В противном случае будет загружена ваша предыдущая страница, и если снова произойдет сбой, вы снова увидите эту пустую страницу.Наконец, я решил это. (Работает до сих пор ..)
Мое решение такое ...
Подготовьте макет для отображения, когда произошла ошибка вместо веб-страницы (грязное сообщение «страница не найдена»). В макете есть одна кнопка «ПЕРЕЗАГРУЗИТЬ» с некоторыми сообщениями-подсказками.
Если произошла ошибка, не забудьте использовать логическое значение и показать подготовленный макет.
Вот мой полный исходник. Проверь это.
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>
источник
Когда веб-просмотр встроен в какое-то настраиваемое представление, так что пользователь почти верит, что он видит собственное представление, а не веб-просмотр, в таком сценарии, показывающая ошибку «страница не может быть загружена», является нелепым. Что я обычно делаю в такой ситуации, так это загружаю пустую страницу и показываю тост, как показано ниже.
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); } });
источник
Ознакомьтесь с обсуждением onReceivedError () в Android WebView . Это довольно долго, но, похоже, консенсус состоит в том, что а) вы не можете остановить появление страницы «веб-страница недоступна», но б) вы всегда можете загрузить пустую страницу после получения ошибки onReceivedError
источник
onReceivedError
вообще не срабатывать. Он правильно запускается в моем коде, когда нет подключения к Интернету.Вы можете использовать
GET
запрос для получения содержимого страницы, а затем отображать эти данные с помощьюWebview
, таким образом вы не используете несколько вызовов сервера. Альтернативу можно использоватьJavascript
для проверкиDOM
объекта на предмет действительности.источник
Возможно, я неправильно понимаю вопрос, но похоже, что вы говорите, что получаете обратный вызов об ошибке, и вы просто спрашиваете, как лучше всего не показывать ошибку? Почему бы вам просто не удалить веб-представление с экрана и / или не показать другое представление поверх него?
источник
Здесь я нашел самое простое решение. проверить это ..
@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); }
А вот и метод InterentConnection () ...
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, который описывается следующим образом:
Этот метод может оказаться полезным. В любом случае, как бы вы это ни реализовали ... проверьте этот код:
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)
источник
Я бы просто изменил веб-страницу на то, что вы используете для обработки ошибок:
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
источник
Сегодня я работал над проблемой избавления от этих раздражающих страниц ошибок 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 () как еще один веб-клиент. По крайней мере, у меня это работает на моем устройстве 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 () позже из-за добавления этой новой страницы в историю навигации.
источник
попробуйте это shouldOverrideUrlLoading , прежде чем перенаправить на другой URL-адрес, проверьте подключение к Интернету на основе этой страницы, должна быть загружена или нет.
источник
переопределить ваш метод WebViewClient
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { view.clearView(); }
view.loadUrl('about:blank')
имеет побочные эффекты, поскольку отменяет загрузку исходного URL-адреса.источник