WebView को "वेब पेज उपलब्ध नहीं है" प्रदर्शित करने से रोकें


88

मेरे पास एक ऐप है जो वेबव्यू का व्यापक उपयोग करता है। जब इस ऐप के उपयोगकर्ता के पास इंटरनेट कनेक्शन नहीं है, तो एक पृष्ठ "वेब पेज उपलब्ध नहीं है" और विभिन्न पाठ दिखाई देता है। क्या मेरे वेबव्यू में इस सामान्य पाठ को नहीं दिखाने का कोई तरीका है? मैं अपनी त्रुटि हैंडलिंग प्रदान करना चाहूंगा।

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 वास्तव में दृश्य को साफ़ नहीं करता है।


3
आप WebView दिखाने से पहले इंटरनेट कनेक्शन की जांच क्यों नहीं करते हैं और अगर कोई इंटरनेट सुविधा उपलब्ध नहीं है तो आप WebView दिखाना छोड़ सकते हैं और इसके बजाय आप बिना इंटरनेट संदेश के अलर्ट या टोस्ट दिखा सकते हैं?
एंड्रो सेल्वा

@JoJo क्या आप किसी उत्तर को सही मान सकते हैं? शायद मेरा: पी
शेरिफ इल्हातिब

जवाबों:


102

सबसे पहले 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");

    }
});

27
पुराने "वेबपेज लोड नहीं किया गया" त्रुटि पृष्ठ संपत्ति से कस्टम त्रुटि पृष्ठ द्वारा प्रतिस्थापित किए जाने से पहले एक सेकंड के एक अंश के लिए दिखाता है
चेएनु मदन

1
चेणु से सहमत। एक बेहतर समाधान होना चाहिए।
जोजुआ

3
1. आप वेब सामग्री को लोड कर सकते हैं जबकि WebView अदृश्य है (और हो सकता है कि उस पर एक प्रगति खराब हो) और यह दिखाएं कि क्या पेज सफलतापूर्वक लोड हुआ है या त्रुटि पर "myerrorpage.html" लोड करें। 2. आपको पता होना चाहिए कि OnReceiveError तब ट्रिगर हो जाएगी जब पेज में लोड होने के बाद चलने वाली JS में OR समस्या लोड करने में समस्याएँ हों (जैसे jQuery फ़ंक्शंस जो document.ready () इवेंट में चलती हैं)। डेस्कटॉप ब्राउज़र - इसके बारे में उपयोगकर्ता को सूचित किए बिना जेएस त्रुटि की अनुमति देगा, जैसा कि मोबाइल ब्राउज़र को करना चाहिए।
फंकस्कूलब्रॉथर

5
view.loadUrl("about:blank");लोड होने से पहले जोड़ें इसे दूसरे के एक अंश के लिए त्रुटि पृष्ठ दिखाने से रोकने के लिए।
आशीष

2
उस myerrorpage.html फ़ाइल को कहाँ रखा जाए? वह Android संपत्ति फ़ोल्डर कहाँ स्थित है?
निवेद कन्नड़

34

सबसे अच्छा समाधान मैंने पाया है कि इस तरह से 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 त्रुटि संदेश के साथ स्थानीय फ़ाइल है)। यह भी सेकंड के एक अंश के लिए अंतर्निहित त्रुटि पृष्ठ को "नहीं" देखने में मदद करता है।
hQuse

4
कृपया ध्यान दें, यदि आप संभाल रहे हैं webView.goBack()तो इस रिक्त पृष्ठ के लिए स्थिति को संभालना सुनिश्चित करें। अन्यथा आपका पिछला पृष्ठ लोड हो जाएगा और यदि फिर से विफल हो गया तो आप इस रिक्त पृष्ठ को फिर से देखेंगे।
चिंतन शाह

तो, इसे संभालने का सबसे अच्छा तरीका क्या है?
MoSoli

@MoSoli यह सब आपकी आवश्यकताओं पर निर्भर करता है। एक खाली पृष्ठ प्रदर्शित करने का विकल्प कुछ कस्टम यूआई या कैश्ड वेबपेज दिखाना होगा।
7

10

अंत में, मैंने इसे हल कर दिया। (यह अब तक काम करता है ..)

मेरा समाधान इस तरह है ...

  1. वेब पेज (एक गंदा 'पेज को संदेश नहीं मिला) के बजाय एक त्रुटि होने पर दिखाने के लिए लेआउट तैयार करें। लेआउट में कुछ गाइड संदेशों के साथ एक बटन, "RELOAD" है।

  2. यदि कोई त्रुटि हुई है, तो बूलियन का उपयोग करना याद रखें और हमारे द्वारा तैयार किए गए लेआउट को दिखाएं।

  3. यदि उपयोगकर्ता "RELOAD" बटन पर क्लिक करता है, तो mbErrorOccured को असत्य पर सेट करें। और mbReloadPressed को सही पर सेट करें।
  4. अगर mbErrorOccured गलत है और mbReloadPressed सही है, तो इसका मतलब है कि वेबव्यू लोडेड पेज सफलतापूर्वक। 'क्योंकि यदि त्रुटि दोबारा हुई, तो mRErrorOccured को onReceivedError (...) पर सेट किया जाएगा।

यहाँ मेरा पूर्ण स्रोत है। इसकी जांच करें।

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>


क्या आप कृपया अपनी संसाधन फ़ाइल साझा कर सकते हैं? मैं नौसिखिया हूँ।
राजन रावल

@RajanRawal मैंने संपादित किया और लेआउट का उदाहरण जोड़ा। :)
सेमीक्रोमेंस

मैं कोई प्रगति पट्टी नहीं देख सकता, लेकिन मैं वहां कोड देख सकता हूं। :-(
राजन रावल

8

जब वेबव्यू को कुछ कस्टम दृश्य में एम्बेड किया जाता है, जैसे कि उपयोगकर्ता लगभग यह मानता है कि वह एक देशी दृश्य देख रहा है, न कि कोई वेबव्यू, ऐसे परिदृश्य में "पृष्ठ लोड नहीं किया जा सकता है" दिखाते हुए त्रुटि पूर्ववत् है। मैं आमतौर पर ऐसी स्थिति में क्या करता हूं, मैं खाली पृष्ठ लोड करता हूं और नीचे एक टोस्ट संदेश दिखाता हूं

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);
            }
        });

7

Android WebView onReceivedError () पर चर्चा देखें । यह काफी लंबा है, लेकिन सर्वसम्मति से ऐसा लगता है कि क) आप "वेब पेज उपलब्ध नहीं है" पृष्ठ को प्रदर्शित होने से रोक नहीं सकते हैं, लेकिन बी) आप हमेशा एक खाली पृष्ठ को लोड करने के बाद लोड कर सकते हैं।


ये लोग onReceivedErrorट्रिगर नहीं होने की बात कर रहे हैं । इंटरनेट न होने पर यह मेरे कोड में सही तरीके से ट्रिगर हो रहा है।
जोजो

2

आप GETपृष्ठ सामग्री प्राप्त करने के लिए एक अनुरोध का उपयोग कर सकते हैं और फिर उस डेटा का उपयोग करके प्रदर्शित कर सकते हैं Webview, इस तरह आप कई सर्वर कॉल का उपयोग नहीं कर रहे हैं। वैकल्पिक आप वैधता के लिए वस्तु की Javascriptजांच करने के लिए उपयोग कर सकते हैं DOM


यह एक अच्छा विचार है, हालांकि, यह वास्तव में दुर्भाग्यपूर्ण है कि हमें ऐसा कुछ करने की आवश्यकता है ...
जेफरी ब्लॉटमैन

2

शायद मैं प्रश्न को गलत समझ रहा हूं, लेकिन लगता है कि आप कह रहे हैं कि आपको कॉलबैक प्राप्त करने में त्रुटि हुई है, और आप बस पूछ रहे हैं कि त्रुटि न दिखाने का सबसे अच्छा तरीका क्या है? आप स्क्रीन से वेब दृश्य को या तो क्यों नहीं हटाते हैं और / या इसके ऊपर कोई अन्य दृश्य दिखाते हैं?


2

यहां मुझे सबसे आसान उपाय मिला। इसकी जांच करो..

   @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;
}

1

मुझे लगता है कि यदि आप ऐसा करने पर जोर देते हैं, तो आप लोडरएल फ़ंक्शन को कॉल करने से पहले यह देख सकते हैं कि संसाधन मौजूद है या नहीं। बस कार्यों को ओवरराइड करें और सुपर को कॉल करने से पहले चेक करें ()

REMARK (शायद ऑफ-टॉपिक): 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)

6
यदि वास्तव में वहां जाने से पहले संसाधन है, तो यह जांचना कि सर्वर पर लोड दोगुना होगा क्योंकि प्रति 1 आभासी अनुरोध में 2 भौतिक अनुरोध होंगे। यह थोड़ा ओवरकिल लगता है।
जोजो

अच्छी तरह से हताश उपाय!
शरीफ इलाक़ेब

1
वैसे भी आप अभी भी इसे अधिभारित कर सकते हैं और HTML सामग्री प्राप्त कर सकते हैं, यह जांचें कि क्या इसमें कोई त्रुटि है। यदि पार्स नहीं किया गया है और इसे प्रदर्शित नहीं किया गया है
शेरिफ एल्काहिब

वास्तव में कोई इसे कैसे लागू करेगा?
जोजो

@JoJo, वास्तव में यह विधि अमान्य url की स्थिति में सर्वर पर लोड को कम कर देती है क्योंकि HEAD प्रतिसाद को लौटाने में 304 या 500 प्रतिसाद लौटाए जाने की तुलना में बहुत छोटा ओवरहेड होता है।
जस्टिन शील्ड

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 पर पाया जा सकता है


0

मैं आज उन चिड़चिड़े Google त्रुटि पृष्ठों को खोदने की इस समस्या पर काम कर रहा हूं। यह एंड्रॉइड उदाहरण कोड के साथ ऊपर और बहुत सारे अन्य मंचों में संभव है (पूछें कि मुझे कैसे पता है):

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();
       }
    }
});

यदि आप इसे एक और वेबक्लिअर के रूप में कंधे में डालते हैं। कम से कम, यह मेरे लिए मेरे 2.3.6 डिवाइस पर काम कर रहा है। हम देखेंगे कि बाद में यह कहां काम करता है। यह केवल मुझे अब निराश करेगा, मुझे यकीन है। GoBack बिट मेरा है। आप इसे नहीं चाह सकते हैं।


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());
      }
 }

0

हम webView की दृश्यता को 0 पर सेट कर सकते हैं (view.INVISIBLE) और कुछ संदेश दिखा सकते हैं। यह कोड लॉलीपॉप पर चलने वाले मेरे ऐप के लिए काम करता है।

@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());
    }

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 () करने की अनुमति नहीं देता है, बाद में इसके कारण नेविगेशन इतिहास में वह नया पृष्ठ जुड़ जाता है।


-1

यह कोशिश करें कि एक पृष्ठ पर आधारित इंटरनेट संयोजन के लिए किसी अन्य यूआरएल की जांच के लिए रीडायरेक्ट करने से पहले, इस ओवेरोइड यूआरएल लोडिंग को लोड किया जाना चाहिए या नहीं।


-1

अपने WebViewClient विधि को ओवरराइड करें

@Override
public void onReceivedError(WebView view, int errorCode,
    String description, String failingUrl) {
    view.clearView();
}

view.loadUrl('about:blank') इसके साइड-इफेक्ट्स हैं, क्योंकि यह मूल URL लोडिंग को रद्द कर देता है।


view.clearView () पदावनत है, देखें stackoverflow.com/questions/3715482/clear-webview-content
silva96
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.