Установить 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");
}
}
}