Aria下载器源码分析
Aria 中文文档: https://aria.laoyuyu.me/aria_doc/
版本:3.8.15
0x01 注册流程
在Activity的onCreate、fragment的onCreate、java的构造函数中使用Aria.download(this).register()
便可以实现注册。
0x0101 Aria类,下载库的统一入口
Aria类仅一个私有的构造方法,无法实例化
1 | private Aria() {} |
0x0102 Aria类的download方法
Aria类中的2个主要静态方法 download, upload, 对应下载和上传两种类型
以下载方法为例,下载,在当前类中调用Aria方法,参数需要使用this,返回对象是 DownloadReceiver
1 | public static DownloadReceiver download(Object obj) { |
- AriaManager是个单例
- 首次会走get方法,最终执行
AriaManager#init()
方法进行初始化 - convertContext()方法会判断当前参数obj是否是Context对象,并返回Context
- 最后都会执行AriaManager单例对象的download()方法,返回一个DownloadReceiver对象
0x0103 AriaManager初始化
1 |
|
- init()方法,双空判断加锁实现AriaManager单例
- 初始化调用 initData() 方法
- 初始化 AriaConfig
- 初始化DB
- 注册APP生命周期回调,Activity销毁自动移除当前对象的receiver
- Aria初始化,异常处理,日志,命令处理器 CommandManager 初始化
0x0104 AriaManager类的download
1 | private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>(); |
- 调用download方法,根据obj和ReceiverType.DOWNLOAD类型生成key,查询mReceivers是否已经存在当前对象的下载功能接收器DownloadReceiver,存在直接返回
- 首次调用,会走到putReceiver方法,新生成一个下载功能接收器DownloadReceiver,并存储在mReceivers中
0x0105 将当前对象注册到Aria
- 调用
DownloadReceiver#register()
方法 - 通过DOWNLOAD注解或者实现DownloadTaskListener接口,调用TaskSchedulers.getInstance().register()将当前类注册到Aria
0x0106 TaskSchedulers注册(TODO)
TaskSchedulers 事件调度器,用于处理任务状态的调度
1 | private Map<String, Map<TaskEnum, Object>> mObservers = new ConcurrentHashMap<>(); |
0x02 下载流程(TODO)
1 | long taskId = Aria.download(this) |
01 DownloadReceiver.load()
1 HttpBuilderTarget.create()
2 BuilderController.create()
3 CmdHelper.createNormalCmd()
4 NormalCmdFactory.createCmd() -> StartCmd
5 EventMsgUtil.getDefault().post(StartCmd) -> mEventQueue.take()
6 EventMsgUtil.sendEvent()
7 StartCmd.executeCmd() -> AbsNormalCmd.startTask()
8 DTaskQueue.createTask(DTaskWrapper wrapper)
9 TaskWrapperManager.getInstance().putTaskWrapper(wrapper)
10 AbsTaskQueue.startTask()
11 DLoadExecutePool.putTask()
12 AbsTask.start()
13 HttpDLoaderUtil.start() -> AbsNormalLoaderUtil.start()
14 NormalLoader.run() -> AbsNormalLoader.run()
15 AbsNormalLoader.startFlow() -> NormalLoader.handleTask()// 启动单线程任务
16 NormalLoader.startThreadTask()
17 NormalTTBuilder.buildThreadTask()
18 ThreadTaskManager.getInstance().startThread()
19 AbsNormalLoader.startTimer() // 启动进度获取定时器
21 ThreadTask.call() // 线程池执行任务回调
22 AbsThreadTaskAdapter.call()
23 HttpDThreadTaskAdapter.handlerThreadTask() // 正式建立Http连接,下载任务
24 HttpDThreadTaskAdapter.readNormal()
25 HttpDThreadTaskAdapter.handleComplete()
26 ThreadTask.updateCompleteState()
27 NormalThreadStateManager.callback -> STATE_COMPLETE
28 BaseListener.onComplete() // 对应的实体类是BaseDListener
29 BaseListener.sendInState2Target() // 将任务状态发送给下载器
0x03 完成事件逆行分析
- IDLoadListener.onComplete()
- NormalLoader.addComponent(IRecordHandler recordHandler) -> ILoaderVisitor.addComponent(IRecordHandler recordHandler) // 处理任务记录
- RecordHandler.checkTaskCompleted() // 检查任务是否已完成
- 遍历TaskRecord中所有的ThreadRecord.isComplete就认为下载完成
0x04 M3U8文件下载过程
M3U8ThreadTaskAdapter.readDynamicFile(InputStream is) // 动态长度文件读取方式
M3U8ThreadTaskAdapter.handleComplete() // 处理完成
ThreadTask.updateCompleteState() // 组装Message消息,发送给VodStateManager.callback -> Handler.Callback
VodStateManager.callback -> STATE_COMPLETE
BaseListener.onComplete() // 对应的实体类是M3U8Listener