lingochamp / okdownload

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

Download error The current offset on block-info isn't update correct, 1648345 != 11469669 on 0 V1.0.7版本还是遇到这个问题,导致任务中断,进度跳变 #415

Open daiqiquan opened 3 years ago

daiqiquan commented 3 years ago

OkDownload Version

v1.0.2-SNAPSHOT

Problem Describe

I occur some problem, I also search on issues and wiki, I even checked the source code, but it can't help, so my real problem is:...

Log

There is the whole log from LogCat when I occur the problem(I know we can use this tool to let log more readable):

noneorone commented 3 years ago

android10版本会遇到网络不稳定时,下载异常中断

mradzinski commented 3 years ago

@oneornone That's not true. I'm on a 100mb/s very stable WiFi and I get this on every download where setConnectionCount is more than 1. It's a library issue, not an Android one.

wys619 commented 3 years ago

the same problem happen on my device: pixel3 running Android 11 . thanks!

slowlow79464 commented 3 years ago

@daiqiquan I face the same problem, and debug it for days. Finnally I found the cause and send the pull request. Hope helps.

hasansidd commented 3 years ago

@Jacksgong, will this fix be pushed to maven any time soon?

Jiang00 commented 3 years ago

@slowlow79464 It has been modified in your way, but this error will still be reported

kutukoff commented 3 years ago

Hi, there!

I use temp fix before author can't approve merge request #425

@slowlow79464 & @mradzinski Thanks for help =)

========================

1. Add Override fixed classes (I created same package name, its doesn't matter)

CustomProcessFileStrategy.class

package com.liulishuo.okdownload.core.file;

import androidx.annotation.NonNull;

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

public class CustomProcessFileStrategy extends ProcessFileStrategy {

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

and CustomMultiPointOutputStream.class

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 CustomMultiPointOutputStream extends MultiPointOutputStream {
    private static final String TAG = "CustomMultiPointOutputStream";
    private final DownloadTask task;

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

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

    @Override
    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 + "]");
        }
    }
}

2. Add in you Application.onCreate() class:

OkDownload.setSingletonInstance(
                new OkDownload.Builder(this)
                        .processFileStrategy(new CustomProcessFileStrategy())
                        .build()
        );

Enjoy!

MZCretin commented 2 years ago

这个解决方案好像并不能完全解决 还是有概率出现问题

svenjung commented 2 years ago

关闭多线程下载,,,

chenlin139 commented 2 years ago

Hi, there!

I use temp fix before author can't approve merge request #425

@slowlow79464 & @mradzinski Thanks for help =)

========================

1. Add Override fixed classes (I created same package name, its doesn't matter)

CustomProcessFileStrategy.class

package com.liulishuo.okdownload.core.file;

import androidx.annotation.NonNull;

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

public class CustomProcessFileStrategy extends ProcessFileStrategy {

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

and CustomMultiPointOutputStream.class

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 CustomMultiPointOutputStream extends MultiPointOutputStream {
    private static final String TAG = "CustomMultiPointOutputStream";
    private final DownloadTask task;

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

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

    @Override
    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 + "]");
        }
    }
}

2. Add in you Application.onCreate() class:

OkDownload.setSingletonInstance(
                new OkDownload.Builder(this)
                        .processFileStrategy(new CustomProcessFileStrategy())
                        .build()
        );

Enjoy!

MultiPointOutputStream 中的close方法不是public,怎么复写?这个问题还有什么解决方法吗

mysiga commented 2 years ago

设置单线程下载已解决 setConnectionCount(1)

SeaWaterBlue commented 2 years ago

设置单线程下载已解决 setConnectionCount(1)

it work

nannan111 commented 3 weeks ago

我策底解决了,哈哈哈