为什么我调用FileDownloader.getImpl().pauseAll(),UI线程会被阻塞呢?
如果在UI线程调用,确实可能会导致掉帧。
但是这个并非BUG,这是一个考虑稳定性与灵活性权衡的结果,并且这些方法可以在任意线程调用,FileDownloader#pauseAll与BaseDownloadTask#pause 都是同步运行的。
其实每个pause操作都是很小的。如果FileDownloadService被设定在独立进程(默认),那么会有一次IPC(基本上平均一次IPC耗时是在1~10ms),这是唯一耗时的部分;如果FileDownloadService不被设定在独立进程(也是运行在UI进程),那么就只需要简单的数据清理,以及简单的pause通知逻辑。
因此FileDownloader#pauseAll的耗时就与任务数有关,通常情况下很快,如果任务较多可能会很慢。
内部如果直接将pauseAll抛到独立线程其实并不麻烦的,但是失去了灵活性,原因是:
FileDownloader#pauseAll耗时是与任务数量有关,因此耗时久并非绝对。pauseAll能够同步执行,立马执行,如果内部将不确定的事件直接异步了,便失去了灵活性。其实pause与start并不相同,start在基本逻辑以后,任务就直接被丢到启动器线程池里了,原因是下载本身就是在非UI线程的,因此这是符合预期的。
如果上层业务逻辑,任务较多,并且原本是放到UI线程调用的,考虑到可能引起掉帧,可以考虑直接将 pauseAll 放到非UI线程调用即可。
希望对你有所帮助。
@Jacksgong 明白了,非常感谢!
恩。
Most helpful comment
如果在UI线程调用,确实可能会导致掉帧。
但是这个并非BUG,这是一个考虑稳定性与灵活性权衡的结果,并且这些方法可以在任意线程调用,
FileDownloader#pauseAll与BaseDownloadTask#pause都是同步运行的。同步调用的原因
一方面
其实每个
pause操作都是很小的。如果FileDownloadService被设定在独立进程(默认),那么会有一次IPC(基本上平均一次IPC耗时是在1~10ms),这是唯一耗时的部分;如果FileDownloadService不被设定在独立进程(也是运行在UI进程),那么就只需要简单的数据清理,以及简单的pause通知逻辑。因此
FileDownloader#pauseAll的耗时就与任务数有关,通常情况下很快,如果任务较多可能会很慢。另一方面
内部如果直接将
pauseAll抛到独立线程其实并不麻烦的,但是失去了灵活性,原因是:FileDownloader#pauseAll耗时是与任务数量有关,因此耗时久并非绝对。pauseAll能够同步执行,立马执行,如果内部将不确定的事件直接异步了,便失去了灵活性。最后
其实
pause与start并不相同,start在基本逻辑以后,任务就直接被丢到启动器线程池里了,原因是下载本身就是在非UI线程的,因此这是符合预期的。建议解决方案
如果上层业务逻辑,任务较多,并且原本是放到UI线程调用的,考虑到可能引起掉帧,可以考虑直接将
pauseAll放到非UI线程调用即可。希望对你有所帮助。