【问题标题】:Set loadURLTImeOutValue on WebView在 WebView 上设置 loadURLTImeOutValue
【发布时间】:2011-10-14 19:08:04
【问题描述】:

我正在使用 PhoneGap 和 Android,并将我的 .html 和 js 文件放在外部服务器上。当我使用以下代码时,应用程序会加载我的外部 .html 文件并且一切正常:

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

但是,当通过WebView 工作时,我似乎无法为WebView 设置loadURLTimeoutValue

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 上设置超时值?

【问题讨论】:

    标签: android cordova android-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());
    

    【讨论】:

    • 如果出现超时,可以尝试在if语句中添加一些控件来验证页面是否加载一半
    • 如果一个页面加载成功,如果你在线程还没有完成运行的情况下加载另一个页面,就会出现问题......另外,你的构造函数不正确,你应该在@中将超时设置为true 987654328@方法!
    • 网站出现问题后如何取消加载?
    • 多次调用onPageFinished如何处理
    • 这不适用于多个并发调用。一个电话会干扰另一个电话。
    【解决方案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;
        }
    }
    

    【讨论】:

    • 这里的“myHandler”指的是什么?我在你之前尝试过这个解决方案,但是我想运行的代码导致了一个异常,说我需要在 UI 线程中运行我的代码。您的解决方案使用“postDelayed”方法,理论上应该在 UI 线程中运行代码,对吗?我只是对“postDelayed”前面的“myHandler”是什么感到困惑?你能用 myHandler 代码充实这个例子吗,或者一个简单的例子来说明如何定义 myhandler 代码。
    • myHandler 大概在主 (UI) 线程中被初始化为 new Handler() 。查看有关 Handler 和 Looper 的 Android 文档以获取更多信息。从文档中不清楚是否会在所有情况下调用 onPageFinished() - 例如如果发生错误或进行了 WebView.stopLoading() 调用。
    • myHandler = new Handler(Looper.myLooper());
    【解决方案3】:

    更改默认超时的正确方法是在config.xml文件中使用标签<preference />,例如:

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

    更多偏好选项,请参考Android Configuration

    【讨论】:

    • Eclipse 中这些首选项的等价物是什么?
    【解决方案4】:
    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;
        }
    });
    

    【讨论】:

    • 这是唯一对我有用的解决方案,因为我需要更新 UI,并从字符串数组加载不同的 url。
    【解决方案5】:

    如果你扩展 CordovaWebView,你应该为了得到 phonegap API,你可以使用以下:

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

    在内部,CordovaWebView 实现了类似于上一篇文章中提出的超时机制(默认超时 = 2000)。

    请注意,这不是一个记录在案的接口,因此将来可能会中断。

    【讨论】:

      【解决方案6】:

      使用 Thread 类困扰我从 run 函数调用 WebView 会导致异常,因为 WebView 是在另一个线程中创建和使用的。 我将使用 AsyncTask 执行此操作。 在此示例中,如果达到超时,我使用 AsyncTask 将错误文件加载到 WebView 中。如果页面加载正确,我会取消 AsyncTask。 onPostExecute 在 UI 线程中运行,因此与 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");
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-22
        • 2011-07-20
        • 2018-06-26
        • 2021-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多