[java] WebView가 “웹 페이지를 사용할 수 없음”을 표시하지 않도록 방지

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

    }
});


답변

내가 찾은 가장 좋은 해결책은 다음과 같이 OnReceivedError 이벤트에 빈 페이지를로드하는 것입니다.

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

    view.loadUrl("about:blank");
}


답변

마침내 나는 이것을 해결했다. (지금까지 작동합니다 ..)

내 솔루션은 다음과 같습니다.

  1. 웹 페이지 대신 오류가 발생했을 때 표시 할 레이아웃을 준비합니다 (더티 ‘페이지를 찾을 수 없음 메시지’). 레이아웃에는 몇 가지 안내 메시지와 함께 “RELOAD”버튼이 하나 있습니다.

  2. 오류가 발생하면 부울 사용을 기억하고 준비한 레이아웃을 표시하십시오.

  3. 사용자가 “RELOAD”버튼을 클릭하면 mbErrorOccured를 false로 설정합니다. 그리고 mbReloadPressed를 true로 설정합니다.
  4. mbErrorOccured가 false이고 mbReloadPressed가 true이면 webview가 페이지를 성공적으로로드했음을 의미합니다. 오류가 다시 발생하면 mbErrorOccured가 onReceivedError (…)에서 true로 설정됩니다.

여기 내 전체 출처가 있습니다. 이것 좀 봐.

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


답변

Android WebView onReceivedError () 에서 토론을 확인하십시오 . 꽤 길지만 합의는 a) “웹 페이지를 사용할 수 없음”페이지가 나타나는 것을 멈출 수는 없지만 b) onReceivedError가 발생하면 항상 빈 페이지를로드 할 수 있다는 것입니다.


답변

GET요청을 사용 하여 페이지 콘텐츠를 가져온 다음을 사용하여 해당 데이터를 표시 Webview할 수 있습니다. 이렇게하면 여러 서버 호출을 사용하지 않습니다. 또는 객체의 유효성 Javascript을 확인하는 데 사용할 수 있습니다 DOM.


답변

아마도 나는 질문을 오해하지만 오류 수신 콜백을 받았다고 말하는 것 같고 오류를 표시하지 않는 가장 좋은 방법이 무엇인지 묻는 것입니까? 화면에서 웹보기를 제거하거나 그 위에 다른보기를 표시하지 않는 이유는 무엇입니까?