这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
下面小编就为大家带来一篇 android 多线程断点下载 - 带进度条和百分比进度显示效果。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
android 多线程断点下载,带进度条和百分比显示,断点下载的临时数据保存到 SD 卡的文本文档中,建议可以保存到本地数据库中,这样可以提高存取效率,从而提高系统性能。
效果:
打开软件:
下载中:
下载完毕:
附代码如下:
- package com.yy.multiDownloadOfBreakPoint;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.text.TextUtils;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import android.widget.Toast;
- /**
- * 多线程断点下载实例
- * @author YUANYUAN
- *
- */
- public class MainActivity extends Activity {
- //下载所使用的线程数
- protected static final int threadCount = 3;
- //下载完毕的标记
- public static final int downloadOver = 1;
- //更新下载进度标记
- public static final int UPDATE_PROGRESS = 0;
- //下载资源的路径输入框
- private EditText et_path;
- //下载的进度条
- private ProgressBar pb;
- //进度显示
- private TextView tv_pb;
- //当前累计下载的数据
- int curDownCount=0;
- //当前活动的下载线程数
- protected static int activeThread;
- //加入消息处理机制
- private Handler handler=new Handler(){
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case downloadOver:
- Toast.makeText(MainActivity.this, "文件已下载完毕!", Toast.LENGTH_LONG).show();
- tv_pb.setText("下载完成");
- break;
- case UPDATE_PROGRESS:
- //更新进度显示
- tv_pb.setText("当前进度:"+(pb.getProgress()*100/pb.getMax())+"%");
- break;
- default:
- break;
- }
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et_path=(EditText) findViewById(R.id.et_path);
- et_path.setText("http://192.168.2.114:8080/sqlite.exe");
- pb=(ProgressBar) findViewById(R.id.pb);
- tv_pb=(TextView) findViewById(R.id.tv_pb);
- }
- /**
- * 开始下载
- * @param view
- */
- public void down(View view){
- //获取下载资源的路径
- final String path=et_path.getText().toString().trim();
- //判断资源路径是否为空
- if (TextUtils.isEmpty(path)) {
- Toast.makeText(this, "请输入下载资源的路径", Toast.LENGTH_LONG).show();
- return;
- }
- //开启一个线程进行下载
- new Thread(){
- public void run() {
- try {
- //构造URL地址
- URL url=new URL(path);
- //打开连接
- HttpURLConnection conn=(HttpURLConnection) url.openConnection();
- //设置请求超时的时间
- conn.setConnectTimeout(5000);
- //设置请求方式
- conn.setRequestMethod("GET");
- //获取相应码
- int code=conn.getResponseCode();
- if (code==200) {//请求成功
- //获取请求数据的长度
- int length=conn.getContentLength();
- //设置进度条的最大值
- pb.setMax(length);
- //在客户端创建一个跟服务器文件大小相同的临时文件
- RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd");
- //指定临时文件的长度
- raf.setLength(length);
- raf.close();
- //假设3个线程去下载资源
- //平均每一个线程要下载的文件的大小
- int blockSize=length/threadCount;
- for (int threadId = 1; threadId <= threadCount; threadId++) {
- //当前线程下载数据的开始位置
- int startIndex=blockSize*(threadId-1);
- //当前线程下载数据的结束位置
- int endIndex=blockSize*threadId-1;
- //确定最后一个线程要下载数据的最大位置
- if (threadId==threadCount) {
- endIndex=length;
- }
- //显示下载数据的区间
- System.out.println("线程【"+threadId+"】开始下载:"+startIndex+"---->"+endIndex);
- //开启下载的子线程
- new DownloadThread(path, threadId, startIndex, endIndex).start();
- //当前下载活动的线程数加1
- activeThread++;
- System.out.println("当前活动的线程数:"+activeThread);
- }
- }else{//请求失败
- System.out.println("服务器异常,下载失败!");
- }
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("服务器异常,下载失败!");
- }
- };
- }.start();
- }
- /**
- * 下载文件的子线程 每一个文件都下载对应的数据
- * @author YUANYUAN
- *
- */
- public class DownloadThread extends Thread{
- private String path;
- private int threadId;
- private int startIndex;
- private int endIndex;
- /**
- * 构造方法
- * @param path 下载文件的路径
- * @param threadId 下载文件的线程
- * @param startIndex 下载文件开始的位置
- * @param endIndex 下载文件结束的位置
- */
- public DownloadThread(String path, int threadId, int startIndex,
- int endIndex) {
- this.path = path;
- this.threadId = threadId;
- this.startIndex = startIndex;
- this.endIndex = endIndex;
- }
- @Override
- public void run() {
- //构造URL地址
- try {
- File tempFile=new File("sdcard/"+threadId+".txt");
- //检查记录是否存在,如果存在读取数据,设置真实下载开始的位置
- if (tempFile.exists()) {
- FileInputStream fis=new FileInputStream(tempFile);
- byte[] temp=new byte[1024];
- int length=fis.read(temp);
- //读取到已经下载的位置
- int downloadNewIndex=Integer.parseInt(new String(temp, 0, length));
- //计算出已经下载的数据长度
- int areadyDown=downloadNewIndex-startIndex;
- //累加已经下载的数据量
- curDownCount+=areadyDown;
- //设置进度条已经下载的数据量
- pb.setProgress(curDownCount);
- //设置重新开始下载的开始位置
- startIndex=downloadNewIndex;
- fis.close();
- //显示真实下载数据的区间
- System.out.println("线程【"+threadId+"】真实开始下载数据区间:"+startIndex+"---->"+endIndex);
- }
- URL url = new URL(path);
- HttpURLConnection conn=(HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(5000);
- conn.setRequestMethod("GET");
- //设置请求属性,请求部分资源
- conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
- int code=conn.getResponseCode();
- if (code==206) {//下载部分资源,正常返回的状态码为206
- InputStream is=conn.getInputStream();//已经设置了请求的位置,所以返回的是对应的部分资源
- //构建随机访问文件
- RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd");
- //设置 每一个线程随机写文件开始的位置
- raf.seek(startIndex);
- //开始写文件
- int len=0;
- byte[] buffer=new byte[1024];
- //该线程已经下载数据的长度
- int total=0;
- while((len=is.read(buffer))!=-1){//读取输入流
- //记录当前线程已下载数据的长度
- RandomAccessFile file=new RandomAccessFile("sdcard/"+threadId+".txt","rwd");
- raf.write(buffer,0,len);//写文件
- total+=len;//更新该线程已下载数据的总长度
- System.out.println("线程【"+threadId+"】已下载数据:"+(total+startIndex));
- //将已下载数据的位置记录写入到文件
- file.write((startIndex+total+"").getBytes());
- //累加已经下载的数据量
- curDownCount+=len;
- //更新进度条【进度条的更新可以在非UI线程直接更新,具体见底层源代码】
- pb.setProgress(curDownCount);
- //更新下载进度
- Message msg=Message.obtain();
- msg.what=UPDATE_PROGRESS;
- handler.sendMessage(msg);
- file.close();
- }
- is.close();
- raf.close();
- //提示下载完毕
- System.out.println("线程【"+threadId+"】下载完毕");
- }
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("线程【"+threadId+"】下载出现异常!!");
- }finally{
- //活动的线程数减少
- activeThread--;
- if (activeThread==0) {
- for (int i = 1; i <= threadCount; i++) {
- File tempFile=new File("sdcard/"+i+".txt");
- tempFile.delete();
- }
- System.out.println("下载完毕,已清除全部临时文件");
- //界面消息提示下载完毕
- Message msg=new Message();
- msg.what=downloadOver;
- handler.sendMessage(msg);
- }
- }
- }
- }
- }
以上这篇 android 多线程断点下载 - 带进度条和百分比进度显示效果就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持 PHPERZ。
(adsbygoogle = window.adsbygoogle || []).push({});
来源: http://www.phperz.com/article/17/0703/336144.html