Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

下载卡死的解决方法 #448

Open
sparkmars321 opened this issue Jan 13, 2021 · 3 comments
Open

下载卡死的解决方法 #448

sparkmars321 opened this issue Jan 13, 2021 · 3 comments

Comments

@sparkmars321
Copy link

sparkmars321 commented Jan 13, 2021

OkDownload Version

v1.0.7

Problem Describe

下载稍大文件就会发生下载进度卡死的问题,导致不会回调taskEnd;将targetSdkVersion改为29,在Android 10上复现概率不低。

Log

日志如下,只摘了这一条:
The current offset on block-info isn't update correct, 2920 != 10006923 on 1.

Reason

MultiPointOutputStream 的 flushProcess 方法没有catch住其他exception,导致刷新下载进度时 syncFuture 线程异常退出 ,使其他下载线程无法同步下载状态而陷入等待状态,导致下载进度卡死。

Solution

修改 MultiPointOutputStream 类的 close 和 flushProcess 方法。该解决方法只保证在下载出错时会回调taskEnd,因此只解决了下载卡死的问题,下载出错问题暂未解决,待后续研究。
具体修改如下:

// close 方法要保证 outputStreamMap 和 noSyncLengthMap 的元素个数相等,只修改这里没有作用
synchronized void close(int blockIndex) throws IOException {
        final DownloadOutputStream outputStream = outputStreamMap.get(blockIndex);
        if (outputStream != null) {
            outputStream.close();
            // outputStreamMap.remove(blockIndex);
            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 + "]");
        }
    }

// flushProcess 增加 catch 块
void flushProcess() throws IOException {
        boolean success;
        final int size;
        synchronized (noSyncLengthMap) {
            // make sure the length of noSyncLengthMap is equal to outputStreamMap
            size = noSyncLengthMap.size();
        }
        final SparseArray<Long> increaseLengthMap = new SparseArray<>(size);
        try {
            for (int i = 0; i < size; i++) {
                final int blockIndex = outputStreamMap.keyAt(i);
                // because we get no sync length value before flush and sync,
                // so the length only possible less than or equal to the real persist
                // length.
                final long noSyncLength = noSyncLengthMap.get(blockIndex).get();
                if (noSyncLength > 0) {
                    increaseLengthMap.put(blockIndex, noSyncLength);
                    final DownloadOutputStream outputStream = outputStreamMap
                            .get(blockIndex);
                    outputStream.flushAndSync();
                }
            }
            success = true;
        } catch (IOException ex) {
            Util.w(TAG, "OutputStream flush and sync data to filesystem failed " + ex);
            success = false;
        } catch (Exception ex) { // 增加这部分,catch住其他类型exception
            Util.w(TAG, "OutputStream flush and sync data to filesystem failed " + ex);
            success = false;
        }

        if (success) {
            final int increaseLengthSize = increaseLengthMap.size();
            long allIncreaseLength = 0;
            for (int i = 0; i < increaseLengthSize; i++) {
                final int blockIndex = increaseLengthMap.keyAt(i);
                final long noSyncLength = increaseLengthMap.valueAt(i);
                store.onSyncToFilesystemSuccess(info, blockIndex, noSyncLength);
                allIncreaseLength += noSyncLength;
                noSyncLengthMap.get(blockIndex).addAndGet(-noSyncLength);
                Util.d(TAG, "OutputStream sync success (" + task.getId() + ") "
                        + "block(" + blockIndex + ") " + " syncLength(" + noSyncLength + ")"
                        + " currentOffset(" + info.getBlock(blockIndex).getCurrentOffset()
                        + ")");
            }
            allNoSyncLength.addAndGet(-allIncreaseLength);
            lastSyncTimestamp.set(SystemClock.uptimeMillis());
        }
    }
@NBXXF
Copy link

NBXXF commented Jan 25, 2021

遇到一样的问题

@xuyang123
Copy link

我也遇到了, 下着下着就没回调了

@Haoxiqiang
Copy link

maybe you could try the pr: #425

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants