lingochamp / okdownload

A Reliable, Flexible, Fast and Powerful download engine.
Apache License 2.0
5.17k stars 773 forks source link

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

Open githubZYQ opened 3 years ago

githubZYQ commented 3 years ago

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();
    }
githubZYQ commented 3 years ago

supplement logs:"targetSdk29" on Android 10, 9, 5.1; Find that error sence "targetSdk29-Android 10",has only "blockEnd:0 ",then "cause:ERROR realCause:java.io.IOException: The current offset on block-info isn't update correct, 3397947 != 8787995 on 2"; Other normal sences has "blockEnd:0, blockEnd:1 ,blockEnd:2 ",then “cause:COMPLETED realCause:null"; download file link: https://www.bus365.com/public/phoneClient/BUS365.apk

`targetSdk29-Android 10.0 2020-11-12 09:54:00.336 15899-15899/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 09:54:00.581 15899-15899/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 09:54:00.774 15899-15899/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 09:54:36.641 15899-15899/cn.nova.phone E/DownloadTask: blockEnd:0 info:[0, 8787996)-current:8787997 2020-11-12 09:54:49.044 15899-15899/cn.nova.phone E/DownloadTask: cause:ERROR realCause:java.io.IOException: The current offset on block-info isn't update correct, 3397947 != 8787995 on 2

targetSdk29-Android 5.1 11-12 10:02:06.787 3164-3164/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:02:07.061 3164-3164/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:02:07.164 3164-3164/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:02:07.164 3164-3164/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:02:40.539 3164-3164/cn.nova.phone E/DownloadTask: blockEnd:0 info:[0, 8787996)-current:0 11-12 10:02:47.603 3164-3164/cn.nova.phone E/DownloadTask: blockEnd:1 info:[8787997, 17575991)-current:0 11-12 10:02:50.444 3164-3164/cn.nova.phone E/DownloadTask: blockEnd:2 info:[17575992, 26363986)-current:0 cause:COMPLETED realCause:null

targetSdk29-Android 9.0 2020-11-12 10:14:29.218 7268-7268/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:14:29.336 7268-7268/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:14:29.369 7268-7268/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:15:09.455 7268-7268/cn.nova.phone E/DownloadTask: blockEnd:2 2020-11-12 10:15:20.452 7268-7268/cn.nova.phone E/DownloadTask: blockEnd:0 2020-11-12 10:15:23.397 7268-7268/cn.nova.phone E/DownloadTask: blockEnd:1 cause:COMPLETED realCause:null

targetSdk28-Android 9.0 2020-11-12 10:34:13.266 13484-13484/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:34:13.915 13484-13484/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:35:01.511 13484-13484/cn.nova.phone E/DownloadTask: blockEnd:0 2020-11-12 10:35:07.780 13484-13484/cn.nova.phone E/DownloadTask: blockEnd:1 2020-11-12 10:35:15.939 13484-13484/cn.nova.phone E/DownloadTask: blockEnd:2 2020-11-12 10:35:15.939 13484-13484/cn.nova.phone E/DownloadTask: cause:COMPLETED realCause:null

targetSdk28-Android 5.1 11-12 10:44:40.201 10097-10097/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:44:40.630 10097-10097/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:44:40.731 10097-10097/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:44:40.804 10097-10097/cn.nova.phone E/DownloadTask: connectEnd:206 11-12 10:45:12.010 10097-10097/cn.nova.phone E/DownloadTask: blockEnd:0 11-12 10:45:23.638 10097-10097/cn.nova.phone E/DownloadTask: blockEnd:2 11-12 10:45:24.070 10097-10097/cn.nova.phone E/DownloadTask: blockEnd:1 11-12 10:45:24.070 10097-10097/cn.nova.phone E/DownloadTask: cause:COMPLETED realCause:null

targetSdk28-Android 10.0 2020-11-12 10:47:04.679 20226-20226/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:47:05.185 20226-20226/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:47:05.265 20226-20226/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:47:05.283 20226-20226/cn.nova.phone E/DownloadTask: connectEnd:206 2020-11-12 10:47:52.555 20226-20226/cn.nova.phone E/DownloadTask: blockEnd:2 2020-11-12 10:47:53.802 20226-20226/cn.nova.phone E/DownloadTask: blockEnd:1 2020-11-12 10:48:01.127 20226-20226/cn.nova.phone E/DownloadTask: blockEnd:0 2020-11-12 10:48:01.127 20226-20226/cn.nova.phone E/DownloadTask: cause:COMPLETED realCause:null`

githubZYQ commented 3 years ago

Happend on Device Android 10,Android11 when targetSdk >= 29 , in the Insue#432 targetSdkVersion 29,Android 10,cause:ERROR realCause:java.io.IOException: The current offset on block-info isn't update correct, 2920 != 10006923 on 1

AkashiWen commented 3 years ago

same issue

wolongalick commented 3 years ago

same issue

wolongalick commented 3 years ago

![Uploading image.png…]()

sametbars commented 3 years ago

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...

GiveNoCode commented 3 years ago

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

soft24 commented 3 years ago

Android v11

1607270463.830 D/DownloadCache: catch unknown error java.io.IOException: The current offset on block-info isn't update correct, 1164202 != 1695779 on 1

harshalbhakta commented 3 years ago

Android version: 11 targetSdk: 29

E/DEBUG: download error java.io.IOException: The current offset on block-info isn't update correct, 48728 != 2246052 on 2 at com.liulishuo.okdownload.core.file.MultiPointOutputStream.inspectComplete(MultiPointOutputStream.java:263) at com.liulishuo.okdownload.core.interceptor.BreakpointInterceptor.interceptFetch(BreakpointInterceptor.java:123) at com.liulishuo.okdownload.core.download.DownloadChain.processFetch(DownloadChain.java:220) at com.liulishuo.okdownload.core.interceptor.RetryInterceptor.interceptFetch(RetryInterceptor.java:57) at com.liulishuo.okdownload.core.download.DownloadChain.processFetch(DownloadChain.java:220) at com.liulishuo.okdownload.core.download.DownloadChain.start(DownloadChain.java:195) at com.liulishuo.okdownload.core.download.DownloadChain.run(DownloadChain.java:247) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923)

ymqq commented 3 years ago

临时修复方案,参考链接,原文链接: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 + "]");
            }
        }
    }
}
blueberry404 commented 2 years ago

I am facing this issue in android 10+ devices. @ymqq solution worked for me. I was not able to use close() method as he specified, therefore I had to add "okdownload" as submodule and modify MultiPointOutputStream class' close() method.

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 + "]");
        }
    }
bloworlf commented 2 years ago

I had to add "okdownload" as submodule and modify MultiPointOutputStream class' close() method.

How did you added okdownload as a submodule? I have plenty of errors when I try to.

blueberry404 commented 2 years ago

@bloworlf As far as I remember, I also faced errors and they were probably due to import paths. I had to spend sometime fixing those errors, and then it was good to go.

bloworlf commented 2 years ago

@bloworlf As far as I remember, I also faced errors and they were probably due to import paths. I had to spend sometime fixing those errors, and then it was good to go.

Yeah, I forgot to comment here that I got it fixed. Anyone using this should be aware of that. Spent 1 or 2 hrs just to import the "okdownload" module: checking gradle files, changing lines of import code...)

Now my main issue is with notifications. When there's a lot of files downloading at once, it doeant correctly update the notifications. The files are downloaded, but some of the notification stay in "ongoing" state.

liuyewang commented 1 year ago

Me too, but I can't change it