Android中多线程断点下载

本文介绍了一种使用多线程技术实现文件下载的方法,包括布局文件定义、主线程操作和下载过程的实现细节。

用手机在网络上下载东西是很常有的事,下面是我自己写的一个简易的多线程下载文件的范例

在布局文件中定义一个按钮和一个进度条(progressbar)

 

在MainActivity中

public class MainActivity extends Activity {
 
 @ViewInject(R.id.et_path)//这个是导入了开源框架包(也可以用findviewbyid)
 EditText et_path;
 @ViewInject(R.id.pb)
 ProgressBar pb;
 @ViewInject(R.id.tv)
 TextView tv;
 int length;
 String path;
 static int count = 3;
 int progress;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        ViewUtils.inject(this);
       
    }
   
    class multithread extends Thread //定义一个类继承Thread类(线程)
    {
     private int start;
     private int end;
     private int i;
     
     

  public multithread(int start, int end, int i) {
   super();
   this.start = start;
   this.end = end;
   this.i = i;
  }
  
  
  

  @Override
  public void run() {
   // TODO Auto-generated method stub
   super.run();
   
   try {
    File file = new File("/sdcard/"+i+".txt");
    if(file.exists())
    {
     FileInputStream fis = new FileInputStream(file);将存入起始点下载的数字取出
     byte[] buffer = new byte[20];
     int nRead = fis.read(buffer);
     String s = new String(buffer,0,nRead);
     int n = Integer.parseInt(s);
     progress = n - start + progress;//目前进度条的大小
     start =Integer.parseInt(s);
     
    }
    
    URL url =new URL(path);
    HttpURLConnection conn =(HttpURLConnection) url.openConnection();
    
    conn.setConnectTimeout(3000);
    conn.setRequestMethod("GET");
    
    conn.setRequestProperty("Range", "bytes="+start+"-"+end);表示下载从start到end之前的数据
    System.out.println(start+"/"+end);
    
    InputStream is = conn.getInputStream();
    
    byte[] buffer = new byte[1024];
    
    RandomAccessFile raf =new RandomAccessFile("/sdcard/pc.exe", "rw");
    
    raf.seek(start);
    
    int nRead =0;
    
    int len=0;
    
    while((nRead = is.read(buffer)) !=0)
    {
     raf.write(buffer,0,nRead);
     
     progress+=nRead;
     
     pb.setProgress(progress);
     
     int value = progress*100/length;
     Message mess =Message.obtain();
     
     mess.obj=value;
     mess.what=0x101;
     handler.sendMessage(mess);
     
     RandomAccessFile record = new RandomAccessFile("/sdcard/"+i+".txt", "rw");
     
     len+=nRead;
     
     record.write((start+len+"").getBytes());
     record.close();
    }
    
    System.out.println(i+"号线程下载完毕!");
    
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }finally
   {
    count--;
    if(count==0)
    {
     for(int i=1;i<=3;i++)
     {
      File file =new File("/sdcard/"+i+".txt");
      file.delete();
     }
    }
   }
   
   
   
   
   
  }
     
    }
   
    Handler handler = new Handler(){
     public void handleMessage(android.os.Message msg) {
      int num = (Integer) msg.obj;
      tv.setText(num+"%");
     };
    };
   
   
   
   
    public void download(View v)
    {
     try {
   path = "http://10.176.179.163:8080/Multidownloadfile/pc.exe";//因为我是在自己电脑上做的,就随便搭建了一个服务器提供下载
   
   URL url = new URL(path);
   
   
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   
   conn.setConnectTimeout(5000);
   conn.setRequestMethod("GET");//这以上都是建立连接
   
   length = conn.getContentLength();得到待下载文件的大小
   pb.setMax(length);设置进度条的大小
   
   System.out.println(length);
   
   RandomAccessFile raf =new RandomAccessFile("/sdcard/pc.exe", "rw");   
   raf.setLength(length);//设置文件的长度
   
   raf.close();
   
   int blockSize = length / 3;//用3个子线程下载
   
   for(int i=1;i<=3;i++)
   {
    int start = blockSize*(i-1);
    int end = blockSize*i-1;
    if(i == 3)
    {
     end = length - 1;
    }
    
    new multithread(start, end, i).start();
   }
   
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }

   
}

转载于:https://my.oschina.net/sjh1995/blog/649491

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值