Установить loadURLTImeOutValue в WebView

Я работаю с PhoneGap и Android и у меня есть файлы .html и js на внешнем сервере. Когда я использую следующий код, приложение загружает мои внешние файлы .html, и все работает нормально:

this.setIntegerProperty("loadUrlTimeoutValue", 60000);
this.loadUrl("http://www.myserver.com");

Однако, когда я работаю через WebView, я не могу установить loadURLTimeoutValue для WebView:

private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);  

try {
     webView = (WebView) findViewById(R.id.webview);    
     webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
     webView.loadUrl("http://www.myserver.com");     
}

Это не работает. Как я могу установить значение времени ожидания на WebView?

Ответ 1

Это обходной путь для моделирования описанного поведения. Вы можете использовать WebViewClient и переопределить метод onPageStarted:

public class MyWebViewClient extends WebViewClient {
    boolean timeout;

    public MyWebViewClient() {
        timeout = true;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                timeout = true;

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(timeout) {
                    // do what you want
                }
            }
        }).start();
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        timeout = false;
    }
}

Если время ожидания истекло, вы можете загрузить, например, страницу с ошибкой...

Чтобы добавить WebViewClient к вам WebView, просто сделайте это:

webView.setWebViewClient(new MyWebViewClient());

Ответ 2

Я использовал это, чтобы установить время для моего WebView:

public class MyWebViewClient extends WebViewClient {

    boolean timeout = true;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        Runnable run = new Runnable() {
            public void run() {
                if(timeout) {
                    // do what you want
                    showAlert("Connection Timed out", "Whoops! Something went wrong. Please try again later.");
                }
            }
        };
        Handler myHandler = new Handler(Looper.myLooper());
        myHandler.postDelayed(run, 5000);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        timeout = false;
    }
}

Ответ 3

Правильный способ изменения тайм-аута по умолчанию - использовать тег <preference /> в файле config.xml, например:

<preference name="loglevel" value="DEBUG" />
<preference name="loadUrlTimeoutValue" value="60000" />
<preference name="errorUrl" value="file:///android_asset/www/connection_error.html" />

Дополнительные параметры предпочтений см. в Настройка Android.

Ответ 4

Если вы расширите CordovaWebView, что вам нужно, чтобы получить API phonegap, вы можете просто использовать следующее:

this.getIntent().putExtra("loadUrlTimeoutValue", 60000);

Внутри, CordovaWebView реализует механизм тайм-аута, аналогичный тем, которые были предложены в предыдущем сообщении (по умолчанию timeout = 2000).

Помните, что это не документированный интерфейс, поэтому он может сломаться в будущем.

Ответ 5

WebView mWebView = findViewById(R.id.web_view);
mWebView.setWebViewClient(new WebViewClient() {
    private volatile boolean timeout;
    private volatile String timeoutOnPageStartedURL;
    private volatile String timeoutCurrentURL;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);

        timeout = true;
        timeoutOnPageStartedURL = url;
        timeoutCurrentURL = view.getUrl();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (timeout) {
                    view.post(new Runnable() {
                        @Override
                        public void run() {
                            String currentURL = view.getUrl();
                            if ((timeoutOnPageStartedURL.hashCode() == currentURL.hashCode()) ||
                                (timeoutCurrentURL.hashCode() == currentURL.hashCode())) {
                                // do what you want with UI   
                            }                                     
                        }
                    });
                }
            }
        }).start();
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        timeout = false;
    }
});

Ответ 6

Использование класса Thread мешает вызову WebView из функции run, что приведет к исключению, так как WebView создается и используется в другом потоке. Я бы выполнил это с AsyncTask. В этом примере я использую AsyncTask для загрузки файла ошибок в WebView, если истекло время ожидания. Если страница загружается правильно, я отменяю AsyncTask. onPostExecute работает в потоке пользовательского интерфейса, поэтому нет проблем с безопасностью потока для взаимодействия с WebView:

private class CustomWebViewClient extends WebViewClient {
    boolean mPageLoaded;
    final int mTimeoutLength = 20000;
    WebView mView;
    TimeoutCheck timeoutCheckTask;

    public CustomWebViewClient()
    {
        super();
        mPageLoaded = false;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        mView = view;

        timeoutCheckTask  = new TimeoutCheck();
        timeoutCheckTask.execute(null,null);
    }

    public void onPageFinished(WebView view, String url) {
        mPageLoaded = true;
        timeoutCheckTask.cancel(true);
    }

    private class TimeoutCheck extends AsyncTask<Void, Void, Void> {
        protected Void doInBackground(Void... params) {
            long count = 0;
            while (count < mTimeoutLength)
            {
                try
                {
                    Thread.sleep( 1000 );
                }
                catch ( InterruptedException e )
                {
                    e.printStackTrace();
                }

                // Escape early if cancel() is called
                if (isCancelled()) break;
                count += 1000;
            }
            return null;
        }

        protected void onPostExecute(Void result) {
            if(!mPageLoaded) {
                mbLoadedErrFile = true;
                //load error file into the webview
                mView.loadUrl("file:///android_asset/url_err_timeout.html");
            }
        }
    }