Android xutils 分析修改 下载进度更新频率


因为在更新进度的时候,有点卡,所以想,减缓进度更新的间隔时间。使其不那么频繁。

直接看代码分析下。

HttpHandler.java 实现了RequestCallBackHandler的下载进度监听


 private ResponseInfo<T> handleResponse(HttpResponse response) throws HttpException, IOException {
        if (response == null) {
            throw new HttpException("response is null");
        }
        if (isCancelled()) return null;

        StatusLine status = response.getStatusLine();
        int statusCode = status.getStatusCode();
        if (statusCode < 300) {
            Object result = null;
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                isUploading = false;
                if (isDownloadingFile) {
                    autoResume = autoResume && OtherUtils.isSupportRange(response);
                    String responseFileName = autoRename ? OtherUtils.getFileNameFromHttpResponse(response) : null;
                    FileDownloadHandler downloadHandler = new FileDownloadHandler();
                   <span style="color:#ff0000;"> result = downloadHandler.handleEntity(entity, this, fileSavePath, autoResume, responseFileName); //在这里我找到了,进度接口实现的实体了,我们点进去看看。</span>
                } else {
                    StringDownloadHandler downloadHandler = new StringDownloadHandler();
                   <span style="color:#ff0000;"> result = downloadHandler.handleEntity(entity, this, charset);</span>
                    if (HttpUtils.sHttpCache.isEnabled(requestMethod)) {
                        HttpUtils.sHttpCache.put(requestUrl, (String) result, expiry);
                    }
                }
            }
            return new ResponseInfo<T>(response, (T) result, false);
        } else if (statusCode == 301 || statusCode == 302) {
            if (httpRedirectHandler == null) {
                httpRedirectHandler = new DefaultHttpRedirectHandler();
            }
            HttpRequestBase request = httpRedirectHandler.getDirectRequest(response);
            if (request != null) {
                return this.sendRequest(request);
            }
        } else if (statusCode == 416) {
            throw new HttpException(statusCode, "maybe the file has downloaded completely");
        } else {
            throw new HttpException(statusCode, status.getReasonPhrase());
        }
        return null;
    }

FileDownloadHandler.java里面,xutils对进度的更新做了如下操作。

如果处于进度更新状态,就让其走间隔更新进度,其他状态不进行间隔设置。

public class FileDownloadHandler {

    public File handleEntity(HttpEntity entity,
                             RequestCallBackHandler callBackHandler,
                             String target,
                             boolean isResume,
                             String responseFileName) throws IOException {
        if (entity == null || TextUtils.isEmpty(target)) {
            return null;
        }

        File targetFile = new File(target);

        if (!targetFile.exists()) {
            File dir = targetFile.getParentFile();
            if (dir.exists() || dir.mkdirs()) {
                targetFile.createNewFile();
            }
        }

        long current = 0;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            FileOutputStream fileOutputStream = null;
            if (isResume) {
                current = targetFile.length();
                fileOutputStream = new FileOutputStream(target, true);
            } else {
                fileOutputStream = new FileOutputStream(target);
            }
            long total = entity.getContentLength() + current;
            bis = new BufferedInputStream(entity.getContent());
            bos = new BufferedOutputStream(fileOutputStream);

            if (callBackHandler != null && !callBackHandler.updateProgress(total, current, true)) {
                return targetFile;
            }

            byte[] tmp = new byte[4096];
            int len;
            while ((len = bis.read(tmp)) != -1) {
                bos.write(tmp, 0, len);
                current += len;
                if (callBackHandler != null) {
                 <span style="color:#ff0000;">   if (!callBackHandler.updateProgress(total, current, false)) {  //进度更新,有更新的频率</span>
                        return targetFile;
                    }
                }
            }
            bos.flush();
            if (callBackHandler != null) {
              <span style="color:#ff0000;">  callBackHandler.updateProgress(total, current, true);//必须更新</span>
            }
        } finally {
            IOUtils.closeQuietly(bis);
            IOUtils.closeQuietly(bos);
        }

        if (targetFile.exists() && !TextUtils.isEmpty(responseFileName)) {
            File newFile = new File(targetFile.getParent(), responseFileName);
            while (newFile.exists()) {
                newFile = new File(targetFile.getParent(), System.currentTimeMillis() + responseFileName);
            }
            return targetFile.renameTo(newFile) ? newFile : targetFile;
        } else {
            return targetFile;
        }
    }

}



最后,我们回到HttpHandler.java里面

    private long lastUpdateTime;

    @Override
    public boolean updateProgress(long total, long current, boolean forceUpdateUI) {
        if (callback != null && this.state != State.CANCELLED) {
            if (forceUpdateUI) {
               <span style="color:#ff0000;"> this.publishProgress(UPDATE_LOADING, total, current); </span>
            } else {
                long currTime = SystemClock.uptimeMillis();
                if (currTime - lastUpdateTime >= callback.getRate()) {
                    lastUpdateTime = currTime;
                   <span style="color:#ff0000;"> this.publishProgress(UPDATE_LOADING, total, current);</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;"> //间隔一定时间进行更新 进度</span><span style="color:#ff0000;">
</span>
                }
            }
        }
        return this.state != State.CANCELLED;
    }


最后,到哪里设置呢。间隔时间呢。

到RequestCallBack.java



    private static final int DEFAULT_RATE = 1000;


    private static final int MIN_RATE = 200;

//修改这里即可。完毕

  public final int getRate() {
        if (rate < MIN_RATE) {
            return MIN_RATE;
        }
        return rate;
    }

或者通过在 callback里面去 setRate(2000)都可以。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。