栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

android多线程断点下载-带进度条和百分比进度显示效果

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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;

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);
  }
  
  
  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();
    
  }
  
  public class DownloadThread extends Thread{
    private String path;
    private int threadId;
    private int startIndex;
    private int 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多线程断点下载-带进度条和百分比进度显示效果就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/158500.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号