因为Android应用程序是java写的,基本上很多java写的程序都可以直接照搬到Android上面,移植性非常Good。这里讲一下多线程下载,就是每个线程都下载自己的那部分,那么就需要平均分配分割线程下载多少,一张图来说明一下。

第一个要点:http头里面有一个”Range”,就是在这里设置从哪里开始下载。

第二个要点:RandomAccessFile,java给出的这个API。

分别开启多个线程,每个线程规定得有下载的大小,然后分别下载,下载下来的inputstream再组合在一起,怎么组合呢,就会用到RandomAccessFile。

downLoad函数                                                                          

public void downLoad() throws Exception {currentProcess = 0;new Thread() {@Overridepublic void run() {URL url;try {url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");int code = conn.getResponseCode();System.out.println("int code = conn.getResponseCode();---------->"+ code);if (code == 200) {// 服务器返回的数据的长度,实际上就是文件的长度int length = conn.getContentLength();System.out.println("文件总长度" + length);// 在客户端本地创建出来一个大小跟服务器端文件大小一样的临时文件
                        RandomAccessFile raf;raf = new RandomAccessFile("/data/data/com.yydcdut.duothread/lala.exe", "rwd");raf.setLength(length);raf.close();// 假设是3个线程去下载资源// 平均每一个线程下载的文件大小int blockSize = length / threadCount;for (int threadId = 1; threadId <= threadCount; threadId++) {// 第一个线程下载的开始位置int startIndex = (threadId - 1) * blockSize;int endIndex = threadId * blockSize;if (threadId == threadCount) {// 最后个线程下载的长度弄得稍微大一点endIndex = length;}System.out.println("线程:" + threadId + "---下载:"+ startIndex + "--->" + endIndex);// 开始下载new DownloadThread(path, threadId, startIndex,endIndex).start();}} else {System.out.println("服务器错误!!!");Message msg = new Message();msg.what = SERVER_ERROR;handler.sendMessage(msg);}} catch (MalformedURLException e1) {// TODO 自动生成的 catch 块
                    e1.printStackTrace();} catch (Exception e) {// TODO 自动生成的 catch 块
                    e.printStackTrace();}super.run();}}.start();}

httpUrlConnection先得到要下载的文件的大小,然后将这个文件分别分为几份(我这里是开启三个线程下载,所以平均分了3份)。还有先建立一个与下载大小一样的文件,通过RandomAccessFile实现。

下载子线程                                                                                   

public class DownloadThread extends Thread {private int threadId;private int startIndex;private int endIndex;private String path;public DownloadThread(String path, int threadId, int startIndex,int endIndex) {super();this.threadId = threadId;this.startIndex = startIndex;this.endIndex = endIndex;this.path = path;}@Overridepublic void run() {File tempFile = new File("/data/data/com.yydcdut.duothread/" + threadId + ".txt");if (tempFile.exists() && tempFile.length() > 0) {try {FileInputStream fis = new FileInputStream(tempFile);byte[] temp = new byte[1024];int leng = fis.read(temp);String downLoadLen = new String(temp, 0, leng);int downloadlenInt = Integer.parseInt(downLoadLen);int alreadyDowlLoad = downloadlenInt - startIndex;currentProcess += alreadyDowlLoad;startIndex = downloadlenInt;// 修改下载的真实的开始位置
                    fis.close();} catch (Exception e) {// TODO 自动生成的 catch 块
                    e.printStackTrace();}}URL url;try {url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);conn.setRequestProperty("Range", "bytes=" + startIndex + "-"+ endIndex);System.out.println("线程真实下载:" + threadId + "下载----" + startIndex+ "---->" + endIndex);int code = conn.getResponseCode();// 从服务器请求全部资源200 如果请求部分资源206System.out.println("threadId--->" + threadId + "----code:"+ code);InputStream is = conn.getInputStream();// 设置请求位置,返回是当前位置对应的文件输入流// 随机写文件的时候从那个位置开始写RandomAccessFile raf = new RandomAccessFile("/data/data/com.yydcdut.duothread/lala.exe","rwd");raf.seek(startIndex);int len = 0;byte[] buffer = new byte[1024];int total = 0;// 记录下载多少了while ((len = is.read(buffer)) != -1) {total += len;raf.write(buffer, 0, len);// System.out.println("线程:"+threadId+"下载了total:"+total);RandomAccessFile file = new RandomAccessFile("/data/data/com.yydcdut.duothread/"+ threadId + ".txt", "rwd");file.write((total + startIndex + "").getBytes());file.close();// 更新进度条synchronized (MainActivity.this) {currentProcess += len;pb.setProgress(currentProcess);Message msg = new Message();msg.what = UPDATE_TEXT;handler.sendMessage(msg);}}is.close();raf.close();System.out.println("线程" + threadId + "下载完毕............");} catch (Exception e) {// TODO 自动生成的 catch 块
                e.printStackTrace();} finally {threadFinish();}super.run();}}

在这里建立了一个txt文件,目的就是将下载到哪的数据存进去,如果网断了再下载的话,实现断点下载,那么下次下载就可以从这里读取数据,然后在写入文件,就不需要重头再分配大小下载了。这里还用到了线程同步去更新进度条。

删除临时txt文件threadFinish

private synchronized void threadFinish() {runningThread--;if (runningThread == 0) {for (int i = 1; i <= 3; i++) {File file = new File("/data/data/com.yydcdut.duothread/" + i + ".txt");file.delete();}System.out.println("文件下载完毕,删除所有的下载记录。。。");Message msg = new Message();msg.what = DOWN_LOAD_FINISH;handler.sendMessage(msg);}}

Handler                                                                                    

private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case DOWN_LOAD_ERROR:Toast.makeText(getApplicationContext(), "下载失败", 0).show();break;case SERVER_ERROR:Toast.makeText(getApplicationContext(), "服务器 错误,下载失败", 0).show();break;case DOWN_LOAD_FINISH:Toast.makeText(getApplicationContext(), "文件下载完毕", 0).show();break;case UPDATE_TEXT:et_path.setText("当前进度:" + pb.getProgress() * 100 / pb.getMax());break;}super.handleMessage(msg);}};

我是天王盖地虎的分割线                                                               

源代码:http://pan.baidu.com/s/1dD1Qx01

MutilDownLoader.zip(JAVA)

多线程下载.zip(Android)

本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3796197.html,如需转载请自行联系原作者

Android -- 多线程下载相关推荐

  1. android 多线程下载,断点续传,线程池

    android 多线程下载,断点续传,线程池 你可以在这里看到这个demo的源码: https://github.com/onlynight/MultiThreadDownloader 效果图 这张效 ...

  2. 更好的Android多线程下载框架

    /*** 作者:Pich* 原文链接:http://me.woblog.cn/* QQ群:129961195* Github:https://github.com/lifengsofts*/ 概述 为 ...

  3. Android多线程下载断点续传

    先上图看卡结果: GITHUB:Android多线程下载断点续传 下载杵这儿 如图所示点击下载就开始下载,点击停止就会停止再次点击下载就会接着下载了. 设计思路是这样的: 首先通过广播将下载信息传递给 ...

  4. android多线程下载原理,安卓多线程断点续传下载功能(靠谱第三方组件,原理demo)...

    一,原生的DownloadManager 从Android 2.3(API level 9)开始,Android以Service的方式提供了全局的DownloadManager来系统级地优化处理长时间 ...

  5. *Android 多线程下载 仿下载助手(改进版)

    首先声明一点: 这里的多线程下载 并不是指的 多个线程下载一个 文件,而是 每个线程 负责一个文件.真正的多线程 希望后面能给大家带来.  -------------  欢迎 爱学习的小伙伴 加群   ...

  6. android多线程下载程序卡死,android 多线程下载与断点续传

    多线程下载: 下载速度更快,服务器对每个线程平分资源,故线程越多,得到的资源越多,下载速度越快. 断点续传: 下载中断,再次下载时从上一次下载结束的位置开始下载,防止重复下载 下载结束后 代码: pa ...

  7. android多线程下载3

    今天跟大家一起分享下android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...

  8. Android 多线程下载文件原理霸气解析介绍 -----文件的下载(3)

    1.首先我们先创建好下载的位置–根据url创建文件. /*** <p>Title: FlieStorageManager</p >* <p>Description: ...

  9. Android 多线程下载以及断点续传

    多线程下载 在日常开发中,我们不可避免的会接到类似这样的需求,下载一个比较大的素材文件或者安装包文件,以此实现APP的自动更新,APP内的素材替换等.由于一般此类文件都比较大,一般会在50M以上,如果 ...

最新文章

  1. 最大整数扩展欧几里得
  2. [DiscuzNt]整合DiscuzNt论坛目前所发现的小BUG及个人简单解决办法
  3. 【云炬mysql数据库笔记】 Work1
  4. 单招计算机专业考多少分可以录取,单招考多少分能过?单招分数线
  5. python串口编程_python串口通信
  6. 腾讯、阿里、百度...大厂招聘火热中,测试员如何才能入大厂?
  7. 03-06 APP-UI自动化测试-等待方式
  8. crontab定时任务语法及应用
  9. 计算机电子设计论文,计算机毕业设计电子信息毕业设计电子信息毕业论文
  10. Vue学习笔记(尚硅谷天禹老师)
  11. python catia 接口_CATIA二次开发工程制图接口:
  12. 雷电2接口_Steinberg 发布旗舰级 32 bit / 384 kHz 雷电 2 音频接口 AXR4
  13. JanusGraph部署方案
  14. 计算机键盘正确指法,键盘指法,详细教您盲打及快速打字指法练习的步骤
  15. 纳米金13nm|金属纳米粒子/Nano gold制备方法-齐岳生物
  16. 使用 X-Frame-Options 防止被iframe 造成跨域iframe 提交挂掉
  17. UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏
  18. 一篇文章带你全面了解“电脑”内外组成
  19. 密码学-->base64隐写
  20. 加密芯片ATSHA204之使用

热门文章

  1. ORA-00913错误:PL/SQL: ORA-00913: too many values
  2. PHP 10条有用的建议
  3. Synology DS412+ 安装与性能篇
  4. python之路---装饰器函数
  5. Android-环境问题
  6. 企业云部署要如何选择IaaS PaaS和SaaS
  7. HDU 4035 Maze(树形概率DP)
  8. LVS学习笔记及总结(思维导图版)
  9. dojo 学习笔记之dojo.query - query(id) 与query(class)的差别
  10. table中嵌套table,如何用jquery来控制奇偶行颜色