FileDownloader.getImpl().pauseAll()会阻塞UI线程

Created on 25 Jul 2016  ·  3Comments  ·  Source: lingochamp/FileDownloader

为什么我调用FileDownloader.getImpl().pauseAll(),UI线程会被阻塞呢?

question

Most helpful comment

如果在UI线程调用,确实可能会导致掉帧。

但是这个并非BUG,这是一个考虑稳定性与灵活性权衡的结果,并且这些方法可以在任意线程调用,FileDownloader#pauseAllBaseDownloadTask#pause 都是同步运行的。

同步调用的原因

一方面

其实每个pause操作都是很小的。如果FileDownloadService被设定在独立进程(默认),那么会有一次IPC(基本上平均一次IPC耗时是在1~10ms),这是唯一耗时的部分;如果FileDownloadService不被设定在独立进程(也是运行在UI进程),那么就只需要简单的数据清理,以及简单的pause通知逻辑。

因此FileDownloader#pauseAll的耗时就与任务数有关,通常情况下很快,如果任务较多可能会很慢。

另一方面

内部如果直接将pauseAll抛到独立线程其实并不麻烦的,但是失去了灵活性,原因是:

  1. FileDownloader#pauseAll耗时是与任务数量有关,因此耗时久并非绝对。
  2. 如果调用方原本就是放到非UI线程,并且原本就希望pauseAll能够同步执行,立马执行,如果内部将不确定的事件直接异步了,便失去了灵活性。

最后

其实pausestart并不相同,start在基本逻辑以后,任务就直接被丢到启动器线程池里了,原因是下载本身就是在非UI线程的,因此这是符合预期的。

建议解决方案

如果上层业务逻辑,任务较多,并且原本是放到UI线程调用的,考虑到可能引起掉帧,可以考虑直接将 pauseAll 放到非UI线程调用即可。


希望对你有所帮助。

All 3 comments

如果在UI线程调用,确实可能会导致掉帧。

但是这个并非BUG,这是一个考虑稳定性与灵活性权衡的结果,并且这些方法可以在任意线程调用,FileDownloader#pauseAllBaseDownloadTask#pause 都是同步运行的。

同步调用的原因

一方面

其实每个pause操作都是很小的。如果FileDownloadService被设定在独立进程(默认),那么会有一次IPC(基本上平均一次IPC耗时是在1~10ms),这是唯一耗时的部分;如果FileDownloadService不被设定在独立进程(也是运行在UI进程),那么就只需要简单的数据清理,以及简单的pause通知逻辑。

因此FileDownloader#pauseAll的耗时就与任务数有关,通常情况下很快,如果任务较多可能会很慢。

另一方面

内部如果直接将pauseAll抛到独立线程其实并不麻烦的,但是失去了灵活性,原因是:

  1. FileDownloader#pauseAll耗时是与任务数量有关,因此耗时久并非绝对。
  2. 如果调用方原本就是放到非UI线程,并且原本就希望pauseAll能够同步执行,立马执行,如果内部将不确定的事件直接异步了,便失去了灵活性。

最后

其实pausestart并不相同,start在基本逻辑以后,任务就直接被丢到启动器线程池里了,原因是下载本身就是在非UI线程的,因此这是符合预期的。

建议解决方案

如果上层业务逻辑,任务较多,并且原本是放到UI线程调用的,考虑到可能引起掉帧,可以考虑直接将 pauseAll 放到非UI线程调用即可。


希望对你有所帮助。

@Jacksgong 明白了,非常感谢!

恩。

Was this page helpful?
0 / 5 - 0 ratings