6

我需要访问 WebView -> WebChromeClient -> onProgressChanged() 中的进度值。进度整数值不会从 0 增加到 100,而是跳跃。这是加载一个页面的示例日志输出和相关的进度号:

DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 30
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 30
DEBUG:  progress : 100
DEBUG:  progress : 10
DEBUG:  progress : 30
DEBUG:  progress : 37
DEBUG:  progress : 45
DEBUG:  progress : 48
DEBUG:  progress : 49
DEBUG:  progress : 50
DEBUG:  progress : 52
DEBUG:  progress : 54
DEBUG:  progress : 56
DEBUG:  progress : 59
DEBUG:  progress : 61
DEBUG:  progress : 63
DEBUG:  progress : 66
DEBUG:  progress : 68
DEBUG:  progress : 70
DEBUG:  progress : 73
DEBUG:  progress : 75
DEBUG:  progress : 77
DEBUG:  progress : 79
DEBUG:  progress : 82
DEBUG:  progress : 84
DEBUG:  progress : 86
DEBUG:  progress : 87
DEBUG:  progress : 88
DEBUG:  progress : 89
DEBUG:  progress : 100

我究竟做错了什么?

代码:

webView.setWebChromeClient(new WebChromeClient() {
    public void onProgressChanged(WebView view, int progress) {
        Log.i(LOG_TAG, "DEBUG: progress : " + progress);
    }
});
4

4 回答 4

5

从我自己的实验中,我发现 onProgressChanged 可以为相同的进度值多次调用相同的 URL(例如:google.com progress = 100 调用两次)。

我还发现 onProgressChanged 会在您加载另一个 url 时被延迟调用。时间表示例:

  1. 加载 google.com
  2. ProgressChanged = 100, webView.geturl(): google.com
  3. 加载 amazon.com
  4. ProgressChanged = 40, webView.getUrl(): amazon.com
  5. ProgressChanged = 100, webView.getUrl(): google.com

在这一点上,我应该提到,在我的实验中,我重写了 shouldOverrideUrlLoading() 以查看重定向,即使我没有看到重定向,上述情况仍然会发生。那么为什么会这样呢?

根据这个答案(为什么 WebChromeClient.onProgressChanged 和 jquery 的 $(document).ready() 回调之间存在明显的延迟?):因为在触发脚本之前加载了页面,所以文档就绪会查找要加载的所有 html 元素首先除了图像和类似的东西,所以你的脚本在加载所有内容之前不会触发,到那时你的 onprogresschanged 已经收到 100%,因为在所有设备都要求检查 js 之后它可能比你的 javascript 具有更高的优先级是否应该被允许,所以在调用这个方法之前它必须经过一些检查。

所以把它们放在一起,这就是你需要做的:

  1. 不要相信 onProgressChanged()。
  2. onPageStarted() 检查您尝试加载的当前 url 是否与 webView.getUrl() 匹配。这是你的起点。将布尔值finishedLoading 设置为false。
  3. 假设在调用 onPageFinished 时加载了您的页面,并且 webView.getUrl() 与您尝试加载的 url 匹配。如果没有重定向,则将 finishedLoading 标志设置为 true。但是,对于重定向,您需要执行第 3 步。
  4. 覆盖应该OverrideurlLoading()。如果新的 url 与最初加载的 (webView.loadUrl(new redirect url)) 不匹配,则加载新的 url,并将 finishedLoading 设置为 false。

代码

    private boolean isCurrentUrl(String url){
        return url.toLowerCase().contains(currentUrl.toLowerCase());
    }

   public void onPageStarted(WebView webView, String url,     
       android.graphics.Bitmap bitmap){

                if (isCurrentUrl(url)){
                    pageLoaded = false;
                }
   }

   public void onPageFinished(WebView webview, String url){
       if (isCurrentUrl(url)){
           pageLoaded = true;
       }
   }

   public boolean shouldOverrideUrlLoading(WebView view, String 
       url){
       if (!currentUrl.equalsIgnoreCase(url)){
           currentUrl = url;
           view.loadUrl(currentUrl);
           return true;
       }
       return false;
   }
于 2015-09-21T21:54:39.787 回答
2

正如@ksasq 在上述评论中指出的那样,初始 URL 导致了许多重定向,因此 onProgressChanged() 被多次调用。

于 2014-03-06T18:49:38.227 回答
2

最好的解决方案是使用 webview 的进度而不是进度(来自方法 onProgressChanged(WebView 视图,int 进度)的整数值)

伪代码,

@Override
public void onProgressChanged(WebView view, int progress) {
       progressBar.setProgress(yourWebView.getProgress());
}

此解决方案适用于所有情况!

于 2018-04-05T12:09:53.660 回答
0

webView有两个进展。webView.getProgress()提供更准确的进度,包括媒体文件的进度。onProgressChanged()进度根据页面的可见性给出相对进度。下面的代码对我来说很好。在这里,我正在使用我的自定义 webView。

import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.webkit.WebChromeClient
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import com.xyz.interfaces.WebViewLoadingProgressListener


class MyWebView : WebView {

    private var webViewLoadingProgressListener: WebViewLoadingProgressListener? = null

    /**
     * to avoid webView progress inconsistency
     * and to get progress in incremental order
     */
    private var loadProgressCounter: Int? = null

    constructor(context: Context) : super(context) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView(context)
    }

    fun setWebViewLoadingProgressListener(webViewLoadingProgressListener: WebViewLoadingProgressListener) {
        this.webViewLoadingProgressListener = webViewLoadingProgressListener
    }

    var totalContentHeight = 0

    private fun initView(context: Context) {
        this.settings.javaScriptEnabled = true
        this.settings.domStorageEnabled = true
        this.settings.setAppCacheEnabled(true)
        this.settings.loadsImagesAutomatically = true
        this.settings.loadWithOverviewMode = true
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            this.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        }


        this.webViewClient = object : WebViewClient() {
            /**
             * to restrict use of external browsing
             */
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                view?.loadUrl(url)
                /**
                 * resetting on page change
                 */
                loadProgressCounter = null
                return true
            }
        }

        this.webChromeClient = object : WebChromeClient() {
            override fun onProgressChanged(view: WebView?, newProgress: Int) {
                /**
                 * use webView.getProgress() for more precise progress
                 */

                /**
                 * allowing incremental progress only
                 */
                if (loadProgressCounter == null || loadProgressCounter!! <= newProgress) {
                    loadProgressCounter = newProgress
                }
                /**
                 * sends progress to required class
                 */
                webViewLoadingProgressListener?.onProgressChange(loadProgressCounter!!)
            }
        }
    }


} 
于 2020-06-06T17:30:57.910 回答