Android中多线程下载列表的封装实现(含进度反馈)
2015-12-23 13:35
387 查看
来源:http://blog.csdn.net/u011638883/article/details/17347015
实现了一下Android中的文件多线程下载模块,支持自定义线程数、断点续传、下载任务的删除,添加等功能,这里封装了一下,功能已全部实现。不过由于使用的是最简单的手动线程数组及消息通知实现,可能还存在某些小问题。笔者会在后面的使用过程中再进行优化完善。先看一下程序测试效果,这里指定了5个下载任务,以及2个下载线程,具体如下:
要运行以上Demo需要自己搭建服务器,和简单,只需要把所需的文件拷贝到Tomcat中的../webapps/ROOT文件夹下即可,以下是笔者的电脑:
其中的0.mp3,1.mp3....11.mp3及本Demo的测试数据。
除此之外还需要引入Afinal类库,已包含在工程下载中了(下载地址在本文最后)
主要类介绍
主界面MainActivity,负责初始化任务参数,用户可以单击列表中的按钮来删除、暂停、继续任务。可以看到有一个refreshHandler负责根据不同的Message来对列表进行不同的刷新操作。
?
下载器调度类DownloaderHelper,负责检查任务队列和下载器数组,并将下载任务分配给空闲的下载器。
?
下载器类Downloader,负责下载数据,将下载状态进行持久化。需要特别说明一下的是,这里的下载器在启动后会进入一个下载循环,即使当前任务断开服务器连接,进入暂停状态,本下载器不会停止,只是进入了wait状态。除此之外,下载器中还包含自定义接口MyDownloadListener,用于向Activity反馈当前的下载状态,以更新界面。
?
自定义动态数组类DynamicArray,是下载任务容器,集合了队列和数组的特性。这是由模块的需求决定的,下载任务应该用优先队列(FIFO特性)来做,但是由于下载队列又需要支持用户的删除某个指定任务的功能(数组访问指定索引特性)。
?
实体Bean类
?
最后,配置参数类Conf
?
几个实现过程中需要注意的地方
1、列表的进度反馈,因为列表需要支持拖动的同时刷新进度,但是如果简单的使用BaseAdapter.notifyDataSetChanged()来刷新的话,会出现两个问题: 一、列表拖动过程中有卡顿现象;二、列表上的按钮将变得难以响应单击事件。那么怎么解决这个问题呢?可以这么思考,如果不使用notifyDataSetChanged来刷新整张列表,而是直接取得列表项上的组件的引用,然后直接修改组件属性的话,就不会出现上述两个问题了。
解决:Google了很多,讲的多少使用ListView.getFirstVisiablePosition和getChildAt()配合使用,我也试了下,发现在拖动列表时会出现显示错乱的情况(主要问题是getChildAt得到的View并不是期望的View)。于是只能再自己想办法了,还好咱够聪明,难不倒咱。这里在getView中使用当前的为每个contentView分配一个id:
?
然后在需要刷新时根据id得到对应的列表项convertView对象,在取得其中的ProgressBar并为其设置进度即可。
?
2、下载器队列的安排,因为有这样特定的需求,所以需要手动管理等待中队列和下载中队列。
3、下载模块的实现,可能不是很难,不过还是有一些需要注意的地方的。
实现了一下Android中的文件多线程下载模块,支持自定义线程数、断点续传、下载任务的删除,添加等功能,这里封装了一下,功能已全部实现。不过由于使用的是最简单的手动线程数组及消息通知实现,可能还存在某些小问题。笔者会在后面的使用过程中再进行优化完善。先看一下程序测试效果,这里指定了5个下载任务,以及2个下载线程,具体如下:
要运行以上Demo需要自己搭建服务器,和简单,只需要把所需的文件拷贝到Tomcat中的../webapps/ROOT文件夹下即可,以下是笔者的电脑:
其中的0.mp3,1.mp3....11.mp3及本Demo的测试数据。
除此之外还需要引入Afinal类库,已包含在工程下载中了(下载地址在本文最后)
主要类介绍
主界面MainActivity,负责初始化任务参数,用户可以单击列表中的按钮来删除、暂停、继续任务。可以看到有一个refreshHandler负责根据不同的Message来对列表进行不同的刷新操作。
?
?
?
?
?
?
1、列表的进度反馈,因为列表需要支持拖动的同时刷新进度,但是如果简单的使用BaseAdapter.notifyDataSetChanged()来刷新的话,会出现两个问题: 一、列表拖动过程中有卡顿现象;二、列表上的按钮将变得难以响应单击事件。那么怎么解决这个问题呢?可以这么思考,如果不使用notifyDataSetChanged来刷新整张列表,而是直接取得列表项上的组件的引用,然后直接修改组件属性的话,就不会出现上述两个问题了。
解决:Google了很多,讲的多少使用ListView.getFirstVisiablePosition和getChildAt()配合使用,我也试了下,发现在拖动列表时会出现显示错乱的情况(主要问题是getChildAt得到的View并不是期望的View)。于是只能再自己想办法了,还好咱够聪明,难不倒咱。这里在getView中使用当前的为每个contentView分配一个id:
?
?
3、下载模块的实现,可能不是很难,不过还是有一些需要注意的地方的。
相关文章推荐
- MaterialDesign 之 NavigationView
- Android:setLatestEventInfo问题
- MaterialDesign 之TabLayout和ViewPager
- Android PopupWindow的封装使用
- MaterialDesign 之 ToolBar学习
- android maxLines ellipsize 配合使用失效,解决办法
- 用JAVA代码为android应用添加一个按钮
- Android 多个页面复用一段布局文件
- Android -- Apk安装简诉
- Android SQLite API的使用(非原创)
- Android Material Design:NavigationView抽屉导航菜单
- Android xml文件解析 SAX,DOM,PULL
- Android AIDL的理解和使用
- EditText怎么把下面的按钮一并推上去
- Android对话框 - Dialog
- 2015年Android 开发有哪些新技术出现
- Android 基于MVC的MVVM模式开发
- Android 基于MVC的MVVM模式开发
- 大帅的有道云笔记
- android 设置EditText只可以输入字母或者数字