Giter Site home page Giter Site logo

Comments (6)

Jacksgong avatar Jacksgong commented on May 12, 2024

请给出Crash堆栈,所使用的版本,最好能够带上下载日志。

你这样描述,定位不了问题。。

from okdownload.

Wangct23 avatar Wangct23 commented on May 12, 2024

如下代码在一个 onClick事件中,重复不停点击就会卡死,闪退。我自己尝试了先暂停再开启就规避了这个问题。

// 会卡死、闪退的代码段
DownloadTask task = new DownloadTask.Builder(bean.getMp4_url(), parentFile)
                                .setFilename(fileName)
                                // the minimal interval millisecond for callback progress
                                .setMinIntervalMillisCallbackProcess(2000)
                                // ignore the same task has already completed in the past.
                                .setPassIfAlreadyCompleted(true)
                                .build();
                        mSerialQueue.enqueue(task);

// 规避掉卡死、闪退的代码段
DownloadTask task = new DownloadTask.Builder(bean.getMp4_url(), parentFile)
                                .setFilename(fileName)
                                // the minimal interval millisecond for callback progress
                                .setMinIntervalMillisCallbackProcess(2000)
                                // ignore the same task has already completed in the past.
                                .setPassIfAlreadyCompleted(true)
                                .build();
                        mSerialQueue.pause();
                        mSerialQueue.enqueue(task);
                        mSerialQueue.resume();

from okdownload.

Jacksgong avatar Jacksgong commented on May 12, 2024

我看你的描述似乎是DownloadSerialQueue存在问题,但是我这边在SingleActivity中改用该动态线性辅助类反复测试,反复的对其进行enqueue操作,并没有复现该问题。

还需要你提供下ANR日志/data/anr/traces.txt;如果是闪退,需要提供闪退堆栈,以便于进一步跟踪你遇到的问题。


以下是一些我自己跑的与该Issue无关的额外的性能报告:

1. 单一任务启动与暂停,在nexus5上实际测试结果两者都是在5ms以内完成

测试数据来自Sample Project中的SingleActivity

image

image

2. 如果是多任务的操作

正如wiki上提到的,多任务下载请使用DownloadTask.enqueue(tasks, listener)DownloadTask.cancel(tasks),okdownload这些接口对多任务操作,做了很多优化。

在小米Mix2上实际测试,疯狂不断点击开始暂停,每次开始与暂停都同时是处理878个任务,测试数据来自Sample Project中的BunchActivity:

  • 878个并行任务使用DownloadTask.enqueue(tasks, listener)启动,首次总耗时在350ms以内(这块耗时主要是在创建任务,生成各id)

image

  • 878个并行任务使用DownloadTask.enqueue(tasks, listener)启动,非首次(同样是重新创建任务启动,只不过不是首次处理这些任务),总耗时在200ms以内

image

  • 878个并行任务使用DownloadTask.cancel(tasks)进行停止,耗时在25ms以内:

image

from okdownload.

Wangct23 avatar Wangct23 commented on May 12, 2024

下面是anr信息:

traces.txt

from okdownload.

Jacksgong avatar Jacksgong commented on May 12, 2024

根据anr的堆栈,可以很清晰的看到

kernel: __switch_to+0x74/0x8c
  kernel: wait_answer_interruptible+0x70/0xac
  kernel: __fuse_request_send+0x2f0/0x350
  kernel: fuse_request_send+0x30/0x40
  kernel: fuse_lookup_name+0xec/0x1e4
  kernel: fuse_lookup+0x34/0x104
  kernel: lookup_real+0x3c/0x7c
  kernel: __lookup_hash+0x50/0x6c
  kernel: lookup_slow+0x48/0xfc
  kernel: path_lookupat+0x678/0x790
  kernel: filename_lookup.isra.30+0x38/0x9c
  kernel: user_path_at_empty+0x60/0xb0
  kernel: user_path_at+0x38/0x48
  kernel: SyS_faccessat+0x98/0x200
  kernel: cpu_switch_to+0x48/0x4c
  native: #00 pc 00041060  /system/lib/libc.so (___faccessat+12)
  native: #01 pc 00021227  /system/lib/libjavacore.so (???)
  native: #02 pc 004439a5  /data/dalvik-cache/arm/system@[email protected] (Java_libcore_io_Posix_access__Ljava_lang_String_2I+104)
  at libcore.io.Posix.access(Native method)
  at libcore.io.BlockGuardOs.access(BlockGuardOs.java:68)
  at java.io.File.doAccess(File.java:284)
  at java.io.File.exists(File.java:364)
  at com.liulishuo.okdownload.StatusUtil.isCompletedOrUnknown(StatusUtil.java:80)
  at com.liulishuo.okdownload.StatusUtil.getStatus(StatusUtil.java:36)
  at org.ciguang.www.stb.module.video.VideoAllDialogFragment.download(VideoAllDialogFragment.java:226)
  at org.ciguang.www.stb.module.video.VideoAllDialogFragment$2.onItemClick(VideoAllDialogFragment.java:162)
  at com.chad.library.adapter.base.BaseQuickAdapter.setOnItemClick(BaseQuickAdapter.java:968)
  at com.chad.library.adapter.base.BaseQuickAdapter$5.onClick(BaseQuickAdapter.java:948)

根据堆栈反应出来的原因是:

  • 最根本的等待时间过长是:内核中对路径相关的处理等待太长导致
  • Native层是: 文件系统相关
  • 虚拟机层代码是: 在VideoAllDialogFragment 226行中调用了StatusUtil.getStatus,而其中在获取状态的时候,有一个地方访问了File#exist()方法,耗时太久导致ANR。

根据原因建议解决方案

根据堆栈的原因,该机器的文件系统可能存在大量耗时过久的原因,对于这类基本的File#exist都有可能导致ANR,建议采用以下方案解决:

  1. 将相关逻辑抛到独立线程处理,不要放在主线程处理
  2. onClick中做逻辑判断,如500ms内不允许重复点击,以防止高频促发,导致ANR

主线程完整堆栈如下:

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 obj=0x74cc3fa0 self=0xf4e76500
  | sysTid=26366 nice=0 cgrp=default sched=0/0 handle=0xf7057b34
  | state=S schedstat=( 4698459942 2268528948 7056 ) utm=393 stm=76 core=1 HZ=100
  | stack=0xff444000-0xff446000 stackSize=8MB
  | held mutexes=
  kernel: __switch_to+0x74/0x8c
  kernel: wait_answer_interruptible+0x70/0xac
  kernel: __fuse_request_send+0x2f0/0x350
  kernel: fuse_request_send+0x30/0x40
  kernel: fuse_lookup_name+0xec/0x1e4
  kernel: fuse_lookup+0x34/0x104
  kernel: lookup_real+0x3c/0x7c
  kernel: __lookup_hash+0x50/0x6c
  kernel: lookup_slow+0x48/0xfc
  kernel: path_lookupat+0x678/0x790
  kernel: filename_lookup.isra.30+0x38/0x9c
  kernel: user_path_at_empty+0x60/0xb0
  kernel: user_path_at+0x38/0x48
  kernel: SyS_faccessat+0x98/0x200
  kernel: cpu_switch_to+0x48/0x4c
  native: #00 pc 00041060  /system/lib/libc.so (___faccessat+12)
  native: #01 pc 00021227  /system/lib/libjavacore.so (???)
  native: #02 pc 004439a5  /data/dalvik-cache/arm/system@[email protected] (Java_libcore_io_Posix_access__Ljava_lang_String_2I+104)
  at libcore.io.Posix.access(Native method)
  at libcore.io.BlockGuardOs.access(BlockGuardOs.java:68)
  at java.io.File.doAccess(File.java:284)
  at java.io.File.exists(File.java:364)
  at com.liulishuo.okdownload.StatusUtil.isCompletedOrUnknown(StatusUtil.java:80)
  at com.liulishuo.okdownload.StatusUtil.getStatus(StatusUtil.java:36)
  at org.ciguang.www.stb.module.video.VideoAllDialogFragment.download(VideoAllDialogFragment.java:226)
  at org.ciguang.www.stb.module.video.VideoAllDialogFragment$2.onItemClick(VideoAllDialogFragment.java:162)
  at com.chad.library.adapter.base.BaseQuickAdapter.setOnItemClick(BaseQuickAdapter.java:968)
  at com.chad.library.adapter.base.BaseQuickAdapter$5.onClick(BaseQuickAdapter.java:948)
  at android.view.View.performClick(View.java:5231)
  at android.view.View.onKeyUp(View.java:9917)
  at android.view.KeyEvent.dispatch(KeyEvent.java:2687)
  at android.view.View.dispatchKeyEvent(View.java:9267)
  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1635)
  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
  ... repeated 1 times
  at com.android.internal.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2395)
  at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1727)
  at android.app.Dialog.dispatchKeyEvent(Dialog.java:753)
  at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2310)
  at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4171)
  at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4130)
  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3672)
  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3728)
  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3691)
  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3820)
  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3702)
  at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3877)
  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3672)
  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3728)
  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3691)
  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3702)
  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3672)
  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3728)
  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3691)
  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3853)
  at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4022)
  at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2253)
  at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1874)
  at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1865)
  at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2230)
  at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
  at android.os.MessageQueue.nativePollOnce(Native method)
  at android.os.MessageQueue.next(MessageQueue.java:323)
  at android.os.Looper.loop(Looper.java:135)
  at android.app.ActivityThread.main(ActivityThread.java:5439)
  at java.lang.reflect.Method.invoke!(Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:936)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)

from okdownload.

Wangct23 avatar Wangct23 commented on May 12, 2024

多谢提供思路,问题已经解决。
将出现anr的那段代码放进io线程后,就再没出现anr,也没有crash。
多谢。

from okdownload.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.