Saya memiliki aplikasi yang memanfaatkan WebView secara ekstensif. Jika pengguna aplikasi ini tidak memiliki koneksi internet, halaman yang mengatakan "halaman web tidak tersedia" dan berbagai teks lainnya muncul. Adakah cara untuk tidak menampilkan teks umum ini di WebView saya? Saya ingin memberikan penanganan kesalahan saya sendiri.
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();
}
}
Saya menemukan WebView-> clearView tidak benar-benar menghapus tampilan.
Jawaban:
Pertama buat halaman kesalahan Anda sendiri di HTML dan taruh di folder aset Anda, sebut saja myerrorpage.html Kemudian dengan onReceivedError:
mWebView.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { mWebView.loadUrl("file:///android_asset/myerrorpage.html"); } });
sumber
view.loadUrl("about:blank");
sebelum loadUrl untuk mencegahnya menampilkan halaman kesalahan selama sepersekian detik.Solusi terbaik yang saya temukan adalah memuat halaman kosong di acara OnReceivedError seperti ini:
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); view.loadUrl("about:blank"); }
sumber
view.loadUrl(noConnectionUrl);
dua kali (di mana noConnectionUrl adalah file lokal dengan pesan kesalahan). Itu juga membantu untuk tidak "melihat" laman kesalahan bawaan selama sepersekian detik.webView.goBack()
maka pastikan untuk menangani kondisi halaman kosong ini. Jika tidak, halaman Anda sebelumnya akan dimuat dan jika gagal lagi maka Anda akan melihat halaman kosong ini lagi.Akhirnya, saya menyelesaikan ini. (Ini berfungsi sampai sekarang ..)
Solusi saya seperti ini ...
Siapkan tata letak untuk menunjukkan kapan kesalahan terjadi alih-alih Halaman Web ('halaman tidak ditemukan pesan' kotor) Tata letak memiliki satu tombol, "RELOAD" dengan beberapa pesan panduan.
Jika terjadi error, Remember using boolean dan tampilkan layout yang kita siapkan.
Ini sumber lengkap saya. Lihat ini.
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); } }; } }
Tambahan: Berikut layoutnya ....
<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>
sumber
Jika tampilan web disematkan dalam beberapa tampilan ubahsuaian sehingga pengguna hampir percaya bahwa dia melihat tampilan asli dan bukan tampilan web, dalam skenario seperti itu menunjukkan kesalahan "laman tidak dapat dimuat" adalah hal yang tidak masuk akal. Apa yang biasanya saya lakukan dalam situasi seperti itu adalah saya memuat halaman kosong dan menampilkan pesan bersulang seperti di bawah ini
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); } });
sumber
Lihat diskusi di Android WebView onReceivedError () . Ini cukup panjang, tetapi konsensusnya tampaknya adalah a) Anda tidak dapat menghentikan kemunculan halaman "halaman web tidak tersedia", tetapi b) Anda selalu dapat memuat halaman kosong setelah mendapatkan onReceivedError
sumber
onReceivedError
tidak memicu sama sekali. Ini memicu dengan benar dalam kode saya ketika tidak ada koneksi internet.Anda dapat menggunakan
GET
permintaan untuk mendapatkan konten halaman dan kemudian menampilkan data tersebut menggunakanWebview
, dengan cara ini Anda tidak menggunakan beberapa panggilan server. Alternatif yang bisa Anda gunakanJavascript
untuk memeriksaDOM
validitas objek.sumber
Mungkin saya salah paham dengan pertanyaannya, tetapi sepertinya Anda mengatakan bahwa Anda menerima panggilan balik yang salah, dan Anda hanya bertanya apa cara terbaik untuk tidak menampilkan kesalahan? Mengapa Anda tidak menghapus tampilan web dari layar dan / atau menampilkan tampilan lain di atasnya?
sumber
Di sini saya menemukan solusi termudah. Lihat ini..
@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); }
Dan inilah metode 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; }
sumber
Saya kira jika Anda bersikeras melakukan ini, Anda bisa memeriksa apakah sumber daya ada sebelum memanggil fungsi loadURL. Cukup timpa fungsinya dan lakukan pemeriksaan sebelum memanggil super ()
KETERANGAN (mungkin di luar topik): Di http, ada metode yang disebut HEAD yang dijelaskan sebagai berikut:
Metode ini mungkin berguna. Pokoknya bagaimana pun Anda menerapkannya ... periksa kode ini:
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 } }
Anda dapat mencoba pemeriksaan ini menggunakan
if(url.openConnection().getContentLength() > 0)
sumber
Saya hanya akan mengubah halaman web menjadi apa pun yang Anda gunakan untuk penanganan kesalahan:
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/");
ini semua dapat ditemukan di http://developer.android.com/reference/android/webkit/WebView.html
sumber
Saya telah mengatasi masalah membuang halaman kesalahan Google yang menjengkelkan hari ini. Ini dimungkinkan dengan kode contoh Android yang terlihat di atas dan di banyak forum lain (tanyakan bagaimana saya tahu):
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(); } } });
JIKA Anda memasukkannya ke shouldOverrideUrlLoading () sebagai satu klien web lagi. Setidaknya, ini berfungsi untuk saya di perangkat 2.3.6 saya. Kami akan melihat di mana lagi ini berfungsi nanti. Itu hanya akan membuatku depresi sekarang, aku yakin. Bit goBack adalah milikku. Anda mungkin tidak menginginkannya.
sumber
Coba ini
@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()); } }
sumber
Kita dapat mengatur visibilitas webView menjadi 0 (view.INVISIBLE) dan menampilkan beberapa pesan. Kode ini berfungsi untuk aplikasi saya yang berjalan di 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()); }
sumber
Saya harus menghadapi masalah ini dan juga mencoba menyelesaikannya dari perspektif yang berbeda. Akhirnya saya menemukan solusi dengan menggunakan satu flag untuk mengecek apakah terjadi error.
... 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()); } }
Dengan cara ini saya menyembunyikan halaman setiap kali ada kesalahan dan menampilkannya ketika halaman telah dimuat lagi dengan benar.
Juga menambahkan penundaan kecil dalam kasus.
Saya menghindari solusi memuat halaman kosong karena tidak memungkinkan Anda melakukan webview.reload () nanti karena menambahkan halaman baru itu dalam riwayat navigasi.
sumber
coba ini shouldOverrideUrlLoading , sebelum redirect ke url lain periksa koneksi internet berdasarkan halaman itu harus dimuat atau tidak.
sumber
ganti metode WebViewClient Anda
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { view.clearView(); }
view.loadUrl('about:blank')
memiliki efek samping, karena membatalkan pemuatan URL asli.sumber