多线程下载:

下载速度更快,服务器对每个线程平分资源,故线程越多,得到的资源越多,下载速度越快。

断点续传:

下载中断,再次下载时从上一次下载结束的位置开始下载,防止重复下载

下载结束后

代码:

package com.itheime.phonemultidown;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

import android.app.Activity;

import android.os.Bundle;

import android.os.Environment;

import android.view.View;

public class MainActivity extends Activity {

static int threadCount = 3;//下载线程数

static int finishedThread = 0;//完成的下载线程数

String fileName = "baidu.html";//要下载的文件名

//确定下载地址,我们用Tomcat做服务器

String path = "http://192.168.61.254:8080/" + fileName;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

//下载按钮点击时,调用此函数

public void click(View v) {

Thread t = new Thread(){//开一个子线程

@Override

public void run() {

try {//发送GET请求,请求这个地址的资源

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setReadTimeout(5000);

conn.setConnectTimeout(5000);

if (conn.getResponseCode() == 200) {

int length = conn.getContentLength();//得到请求资源文件的长度

File file = new File(Environment.getExternalStorageDirectory(), fileName);

//生成临时文件

RandomAccessFile raf = new RandomAccessFile(file, "rwd");

raf.setLength(length);//设置临时文件的大小

raf.close();

int size = length / threadCount;//计算每个线程应该下载多少字节

for (int i = 0; i < threadCount; i++) {

int startIndex = i * size;//计算线程下载的开始和结束位置

int endIndex = (i + 1) * size - 1;

if (i == threadCount - 1) {//最后一个线程,下到文件结束

endIndex = length - 1;

}

new DownLoadThread(startIndex, endIndex, i).start();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

};

t.start();

}

class DownLoadThread extends Thread {//下载线程内部类

int startIndex;

int endIndex;

int threadId;

public DownLoadThread(int startIndex, int endIndex, int threadId) {

super();

this.startIndex = startIndex;

this.endIndex = endIndex;

this.threadId = threadId;

}

@Override

public void run() {

try {

//生成一个专门记录下载进度的临时文件

File progressFile = new File(Environment.getExternalStorageDirectory(),

threadId + ".txt");

//判断进度临时文件是否存在

if (progressFile.exists()) {

FileInputStream fis = new FileInputStream(progressFile);

BufferedReader br = new BufferedReader(new InputStreamReader(fis));

//从进度临时文件中取出上一次的下载总进度,与原本的开始位置相加,得到新的开始位置

startIndex += Integer.parseInt(br.readLine());

fis.close();

}

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setReadTimeout(5000);

conn.setConnectTimeout(5000);

//设置本次http请求所请求数据的区间

conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);

//请求部分数据,成功的响应码为206

if (conn.getResponseCode() == 206) {

//流里此时只有1/3原文件的数据

InputStream is = conn.getInputStream();

byte[] b = new byte[1024];

int len = 0;

File file = new File(Environment.getExternalStorageDirectory(), fileName);

//拿到临时文件的输出流

RandomAccessFile raf = new RandomAccessFile(file, "rwd");

//把文件的写入位置移动至startIndex

raf.seek(startIndex);

int total = 0;

while ((len = is.read(b)) != -1) {

raf.write(b, 0, len);//每次读取流里的数据后,把数据写入临时文件

total += len;

//System.out.println("线程" + threadId + "下载了" + total);

RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");

//每次读取流里的数据后,把当前线程下载的总进度写入进度临时文件中

progressRaf.write((total + "").getBytes());

progressRaf.close();

}

//System.out.println("线程" + threadId + "下载完毕----------------");

raf.close();

finishedThread++;

synchronized(path) {

if (finishedThread == threadCount) {//所有线程下载完毕后将进度临时文件删除

for (int i = 0; i < threadCount; i++) {

System.out.println("delete " + i);

File f = new File(Environment.getExternalStorageDirectory(), i + ".txt");

f.delete();

}

finishedThread = 0;

}

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

布局文件:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="${relativePackage}.${activityClass}" >

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="开始下载"

android:onClick="click"

/>

配置文件添加权限:

android多线程下载程序卡死,android 多线程下载与断点续传相关推荐

  1. android通知栏应用程序更新,Android App自动更新之通知栏下载

    本文实例为大家分享了Android App自动更新通知栏下载的具体代码,供大家参考,具体内容如下 版本更新说明 这里有调用UpdateService启动服务检查下载安装包等 1. 文件下载,下完后写入 ...

  2. Android Killer 高版本卡死,Android Killer反编译卡死的一个解决方案

    半吊子安卓逆向水平,也就会用android killer看看反编译的java源码...玩ctf的时候经常android killer莫名卡死,大致如图: 一般看安卓题就为了换换脑子冷静下,几次碰到这个 ...

  3. 嵌入式linux如何下载程序,Linux平台的下载程序-嵌入式系统-与非网

    有许多网络文件下载工具可以在Windows平台下很好地工作,如NetAnts."网际快车".TelePro等,还有像WebZip那样功能强大的离线浏览器.这些工具使我们可以在Win ...

  4. android做拨号程序代码,Android开发手机拨号程序实现实例源码介绍

    Android开发手机拨号程序实现实例源码介绍,在上一篇文章中,我们实现了第一个程序:helloWorld,并成功测试完成.还给大家介绍了Android项目结构和说明.现在写一个手机拨号程序: 首先, ...

  5. android 平板安装程序开发者,android – 限制平板电脑中的应用安装

    我有一个 Android应用程序,我想在Tablet中停止安装此应用程序.我搜索了很多网站.我有一些想法并遵循了.但这不是限制. 以下是我访问过的一些网站. 我已尝试使用支持屏幕仍然应用程序正在平板电 ...

  6. android 清除应用程序数据,Android – 通过“清除数据”设置选项阻止正在删除的应用程序数据或文件...

    我有一个Android应用程序,可以在少量文件中存储大约25-40K的私有应用程序数据. 默认情况下,系统将这些文件存储在目录/ data / data /'my app package'/ file ...

  7. Linux arm 下载程序,arm-linux—gcc如何下载安装

    ubuntu下交叉编译环境构建(arm-linux-gcc-4.4.3-20100728.tar.gz ) 1.下载arm-linux-gcc-4.4.3-20100728.tar.gz到任意的目录下 ...

  8. android摄像头监控打电话卡死,Android应用开发Android8.0平台Camera monkey拷机卡死异常解决方案...

    本文将带你了解Android应用开发Android8.0平台Camera monkey拷机卡死异常解决方案,希望本文对大家学Android有所帮助. Android8.0平台Camera monkey ...

  9. 升级魅族android的应用程序,魅族Android 4.4 Flyme升级教程

    注意事项: 1)已ROOT,或安装安全类软件进行了Android签名漏洞修补的用户,请务必在升级时清除数据,否则可能会无法开机.清除数据会造成联系人等个人资料丢失,请注意同步备份; 2)从低版本升级到 ...

最新文章

  1. 可恶的MSSQL 内部 SQL Server 错误。(臭BUG)
  2. 电脑有摄像头吗_知道ip地址就能入侵摄像头吗?
  3. java过程调用语句_Java之流程控制语句
  4. java之 Timer 类的使用以及深入理解
  5. shadows a parameter
  6. [html] 如何禁止手机端页面缩放?
  7. js 将图片置灰_艾叶灰千万别扔——艾叶灰的神奇功效
  8. css 中 float 和 clear 的作用
  9. 排序函数c语言流程图,各种排序的流程图 大家帮忙弄一下
  10. 《AutoCAD 2014中文版实用教程》一一2.2 圆类命令
  11. Pycharm连接Mysql问题: Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon
  12. 关于欧几里德第五公设的感言
  13. redis smembersmap_Redis五种数据类型
  14. 计算机网络原理自考挂科率,3个“挂科率高”的专业,补考更是难上加难,看你专业上榜了吗...
  15. java GIF拆分和压缩处理
  16. 第十一届 蓝桥杯 单片机设计与开发项目 决赛
  17. 微信小程序 app.wxss css 不生效
  18. 双能CT的基本原理及理解笔记
  19. Logback 学习笔记
  20. 游戏版号停发和疫情反复的这半年,UWA如何躬身入局?

热门文章

  1. 隐秘历史:那场国产金融技术的“核武器试爆”
  2. python学习 爬取中华英才网工作职位
  3. TikTok账号被封,如何申诉?
  4. matlab求同构数
  5. 在pycharm中使用pyqt5
  6. WK2204 - spi转uart调试记录
  7. 每个工程师都应该知道的事——射频发射机功率怎么测量
  8. 无线点菜系统01(需求分析)
  9. 关于安装Ubuntu20.04重启后反复进入bios界面
  10. 身体即密码:解锁好莱坞大片生物特征识别黑科技