android代码模拟下载地址,android实现下载的核心代码

该博客主要介绍了在Android中使用多线程实现文件下载的方法。通过设定线程数量,计算每个线程的下载范围,利用HttpURLConnection连接服务器获取文件,使用RandomAccessFile进行文件写入,并设置进度条显示下载进度,最后实现多线程协同完成文件下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:使用多线程实现下载

private EditText etpath;//服务地址

private LinearLayout ll ;

// 访问服务器

String path ;

// 设定线程的数量

int threadcount = 3;

//定义正在执行的线程数量

int runningThreadcount = threadcount ;

//建一个集合存放进度条

List list = new ArrayList() ;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

etpath = (EditText) findViewById(R.id.etpath);

ll = (LinearLayout) findViewById(R.id.ll) ;

// 加载进度条控件

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

ProgressBar pb = (ProgressBar)View.inflate(this, R.layout.pb, null) ;

}

}

public void download(View view){

//将进度条加入到线性组件中显示出来

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

ll.addView(list.get(i));}

new Thread() {

public void run() {

path = etpath.getText().toString().trim();

if (TextUtils.isEmpty(path)) {

runOnUiThread(new Runnable() {

@Override

public void run() {

Toast.makeText(MainActivity.this, "路径不能为空", 0)

.show();

}

});

return;

}

// 下载文件

try {

// 创建连接服务器对象

URL url = new URL(path);

HttpURLConnection http = (HttpURLConnection) url

.openConnection();

// 设定连接参数

http.setRequestMethod("GET");

// 设定连接的超时时间

http.setConnectTimeout(5000);

// 获取返回的状态吗

int code = http.getResponseCode();

if (code == 200) {

// 获得返回的文件的大小

int length = http.getContentLength();

// 2.创建一个文件和下载的文件大小一样

RandomAccessFile raf = new RandomAccessFile(

getFileName(path), "rw");

// 设置文件的大小

raf.setLength(length);

// 3.启动多个线程下载文件

for (int id = 0; id < threadcount; id++) {

// 计算每个线程要下载的区块大小

int blocksize = length / threadcount;

// 计算每个线程下载的开始和结束位置

int startIndex = id * blocksize;

int endIndex = (id + 1) * blocksize - 1;

// 特殊情况:最后一个线程需要承担更多的数据

if (id == threadcount - 1) {

endIndex = length - 1;

}

// 启动线程下载数据

DownLoadThread dlt = new DownLoadThread(path, id,

startIndex, endIndex);

dlt.start();

}

}

} catch (Exception e) {

e.printStackTrace();

runOnUiThread(new Runnable() {

@Override

public void run() {

Toast.makeText(MainActivity.this, "网络连接错误", 0).show() ;

}

}) ;

}

};

}.start();

}

//专门下载的类

// 专门下载的类

public class DownLoadThread extends Thread {

private String path;

private int id;

private int startIndex;

private int endIndex;

public DownLoadThread(String path, int id, int startIndex, int endIndex) {

this.path = path;

this.id = id;

this.startIndex = startIndex;

this.endIndex = endIndex;

}

@Override

public void run() {

//设置进度条

ProgressBar pb =  list.get(id) ;

int total = 0;// 记录每个线程已经下载了多少字节

try {

URL url = new URL(path);

HttpURLConnection http = (HttpURLConnection) url

.openConnection();

http.setRequestMethod("GET");

http.setConnectTimeout(5000);

// 读取相应的文件,判断文件是否存在,存在的话,应读取里面的数据

//拿到sd卡的文件an存储路径

String cunPath = Environment.getExternalStorageDirectory().getAbsolutePath() ;

File file = new File(cunPath + "/" + id + ".txt");

if (file.exists() && file.length() > 0) {

FileInputStream fis = new FileInputStream(file);

BufferedReader br = new BufferedReader(

new InputStreamReader(fis));

total = Integer.parseInt(br.readLine());

br.close();

// 改变线程下载的起始位置

startIndex =  startIndex + total;

System.out.println("线程" + id + "下载的真实范围:" + startIndex

+ "~" + endIndex);

}

//设置最大值

pb.setMax(endIndex-startIndex) ;

// 注意,一定要设置一个请求头(范围),指定此线程要下载的数据的范围

http.setRequestProperty("Range", "bytes=" + startIndex + "-"

+ endIndex);

int code = http.getResponseCode();

// 200代表的是服务器把数据向客户端传输完毕,206代表的是服务端传输局部数据完毕

System.out.println("code =" + code);

if (code == 206) {

InputStream is = http.getInputStream();

// 拿到已经在硬盘上的对应的文件

RandomAccessFile raf = new RandomAccessFile(

getFileName(path), "rw");

// 将文件的指针移动到开始写入的位置

raf.seek(startIndex);

// 将流中的数据写入到文件中

byte[] bs = new byte[1024];

int b = 0;

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

raf.write(bs, 0, b);

total += b;

// 真正同步写入到底层的存储设备上

RandomAccessFile f = new RandomAccessFile(cunPath + "/" + id + ".txt",

"rws");

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

f.close();

//改变进度条的当前位置

pb.setProgress(total) ;

}

raf.close();

is.close();

System.out.println("线程" + id + "下载完毕");

System.out.println("线程" + id + "下载的范围是:" + startIndex

+ " ~" + endIndex);

runningThreadcount-- ;

System.out.println(runningThreadcount);

if(runningThreadcount == 0){

//所有的线程都下载完毕了

runOnUiThread(new Runnable() {

@Override

public void run() {

Toast.makeText(MainActivity.this, "文件下载成功", 0).show() ;

}

}) ;

}

// 将对应的临时文件删除

File tempFile = new File(cunPath + "/" + id + ".txt");

if (tempFile.exists())

tempFile.delete();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

* 通过用户传递的路径拿到文件名

*

* @param path

* @return

*/

public static String getFileName(String path) {

String externalPath = Environment.getExternalStorageDirectory().getAbsolutePath() ;

return  externalPath + "/" +path.substring(path.lastIndexOf("/") + 1);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值