okdownload: targetSdkVersion 29,Android 10,cause:ERROR realCause:java.io.IOException: The current offset on block-info isn't update correct, 2920 != 10006923 on 1

OkDownload Version

okdownload:1.0.7

Problem Describe

targetSdkVersion 29,Android 10,taskEnd with “cause:ERROR realCause:java.io.IOException: The current offset on block-info isn’t update correct, 2920 != 10006923 on 1”.

Log

2020-11-11 17:12:41.688 16243-16243/cn.nova.phone E/DownloadTask: cause:ERROR realCause:java.io.IOException: The current offset on block-info isn’t update correct, 2920 != 10006923 on 1 2020-11-11 16:43:01.934 3505-20805/? I/DownloadState: 10356 stop download, curr: 176184008, base: 176167960, delta: 16048 2020-11-11 16:43:01.934 3505-20805/? I/DownloadState: @@@@@@@@@@@@ uid :10356 download :false

download file link: https://www.bus365.com/public/phoneClient/BUS365.apk

{
String apkUrl = "https://www.bus365.com/public/phoneClient/BUS365.apk";
        if (StringUtil.isEmpty(apkUrl)) {
            return;
        }
        //不拼接时间将开启断点续传,正式的cdn有支持,开发模拟都不支持。
        Map<String, String> params = new HashMap<>(0);
        //拼接时间
        params.put("time", String.valueOf(System.currentTimeMillis()));
        //拼接参数获取最后的url
        apkUrl = UrlSkipTool.getLoadUrl(apkUrl, params);
        String sdpath = Util.getDiskCacheDir(getApplicationContext());
        String name = getString(R.string.app_name) + ".apk";
        //下载
        DownloadTask.Builder builder = new DownloadTask.Builder(apkUrl, sdpath, name)
                // the minimal interval millisecond for callback progress
                .setMinIntervalMillisCallbackProcess(500)
                //Set whether need to pre allocate length for the file after get the resource-length from trial-connection.
                .setPreAllocateLength(true)
                // do re-download even if the task has already been completed in the past.
                .setPassIfAlreadyCompleted(false);
        builder.addHeader("Accept-Encoding", "*");
        mDownloadTask = builder.build();
        mDownloadTask.enqueue(new DownloadListener4() {
            @Override
            public void taskStart(@NonNull DownloadTask task) {
                if (mDownloadHandler != null) {
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_PROGRESS);
                    msg.obj = 0;
                    mDownloadHandler.sendMessage(msg);
                }
            }

            @Override
            public void connectStart(@NonNull DownloadTask task, int blockIndex, @NonNull Map<String, List<String>> requestHeaderFields) {
                if (mDownloadHandler != null) {
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_PROGRESS);
                    msg.obj = 0;
                    mDownloadHandler.sendMessage(msg);
                }
            }

            @Override
            public void connectEnd(@NonNull DownloadTask task, int blockIndex, int responseCode, @NonNull Map<String, List<String>> responseHeaderFields) {

            }

            @Override
            public void infoReady(DownloadTask task, @NonNull BreakpointInfo info, boolean fromBreakpoint, @NonNull Listener4Assist.Listener4Model model) {
                int totalLength = (int) info.getTotalLength();
                if (totalLength > 0) {
                    totalFile = totalLength;
                }
                if (mDownloadHandler != null) {
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_PROGRESS);
                    msg.obj = 0;
                    mDownloadHandler.sendMessage(msg);
                }
            }

            @Override
            public void progressBlock(DownloadTask task, int blockIndex, long currentBlockOffset) {

            }

            @Override
            public void progress(DownloadTask task, long currentOffset) {
                //进度更新
                int b = 0;
                if (totalFile > 0) {
                    b = (int) ((currentOffset * 1.0f / totalFile) * 100);
                }
                if (mDownloadHandler != null) {
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_PROGRESS);
                    msg.obj = b;
                    mDownloadHandler.sendMessage(msg);
                }
            }

            @Override
            public void blockEnd(DownloadTask task, int blockIndex, BlockInfo info) {

            }

            @Override
            public void taskEnd(DownloadTask task, EndCause cause, @Nullable Exception realCause, @NonNull Listener4Assist.Listener4Model model) {
                if (mDownloadHandler == null) {
                    return;
                }
                if (cause == EndCause.COMPLETED) {
                    //下载完成
                    File file = task.getFile();
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_DONE);
                    msg.obj = file;
                    mDownloadHandler.sendMessage(msg);
                } else if (cause == EndCause.CANCELED) {
                    Logger.e("DownloadTask", "cause:" + String.valueOf(cause) + " realCause:" + realCause);
                } else {
                    //下载出错
                    Message msg = mDownloadHandler.obtainMessage(INT_UPDATE_FAIL);
                    mDownloadHandler.sendMessage(msg);
                    Logger.e("DownloadTask", "cause:" + String.valueOf(cause) + " realCause:" + realCause);
                }
            }
        });
    }

/**
     * 拼接参数获取需要load的url
     *
     * @param url    地址
     * @param params 参数
     * @return
     */
    public static String getLoadUrl(String url, Map<String, String> params) {
        if (TextUtils.isEmpty(url) || params == null) {
            return url;
        }
        Uri.Builder builder = Uri.parse(url).buildUpon();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (TextUtils.isEmpty(entry.getKey())) {
                continue;
            }
            builder.appendQueryParameter(entry.getKey(), entry.getValue());
        }
        return builder.toString();
    }

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 1
  • Comments: 15

Most upvoted comments

same issue

临时修复方案,参考链接,原文链接:https://blog.csdn.net/Kstar_Ming/article/details/115909863


package com.liulishuo.okdownload.core.file;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.core.Util;
import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo;
import com.liulishuo.okdownload.core.breakpoint.DownloadStore;

import java.io.IOException;

public class HotFixedProcessFileStrategy extends ProcessFileStrategy {

    @Override
    @NonNull
    public MultiPointOutputStream createProcessStream(@NonNull DownloadTask task,
                                                      @NonNull BreakpointInfo info,
                                                      @NonNull DownloadStore store) {
        return new HotFixedMultiPointOutputStream(task, info, store);
    }


    class HotFixedMultiPointOutputStream extends MultiPointOutputStream {
        private static final String TAG = "HotFixedMultiPointOutputStream";
        private final DownloadTask task;

        HotFixedMultiPointOutputStream(@NonNull final DownloadTask task,
                                       @NonNull BreakpointInfo info,
                                       @NonNull DownloadStore store,
                                       @Nullable Runnable syncRunnable) {
            super(task, info, store);
            this.task = task;
        }

        public HotFixedMultiPointOutputStream(@NonNull DownloadTask task,
                                              @NonNull BreakpointInfo info,
                                              @NonNull DownloadStore store) {
            this(task, info, store, null);
        }

        @Override
        public synchronized void close(int blockIndex) throws IOException {
            final DownloadOutputStream outputStream = outputStreamMap.get(blockIndex);
            if (outputStream != null) {
                outputStream.close();
                synchronized (noSyncLengthMap) {
                    // make sure the length of noSyncLengthMap is equal to outputStreamMap
                    outputStreamMap.remove(blockIndex);
                    noSyncLengthMap.remove(blockIndex);
                }
                Util.d(TAG, "OutputStream close task[" + task.getId() + "] block[" + blockIndex + "]");
            }
        }
    }
}

Google forces application to have targetSdk to 29 to update I cannot update application due to this issue

Please someone find a proper fix for this issue.

I’m limiting the block count to 1 to bypass this issue for now. But there is no reason to use this library if I cannot download in multiple blocks…