zoukankan      html  css  js  c++  java
  • Android开发之多线程下载、断点续传、进度条和文本显示

    代码实现了在Android环境下的多线程下载、断点续传、进度条显示和文本显示百分数:

      1 import java.io.BufferedReader;
      2 import java.io.File;
      3 import java.io.FileInputStream;
      4 import java.io.InputStream;
      5 import java.io.InputStreamReader;
      6 import java.io.RandomAccessFile;
      7 import java.net.HttpURLConnection;
      8 import java.net.URL;
      9 
     10 
     11 import android.os.Bundle;
     12 import android.os.Environment;
     13 import android.os.Handler;
     14 import android.app.Activity;
     15 import android.view.Menu;
     16 import android.view.View;
     17 import android.widget.ProgressBar;
     18 import android.widget.TextView;
     19 
     20 public class MainActivity extends Activity {
     21 
     22     static int ThreadCount = 3;
     23     static int finishedThread = 0;
     24     
     25     int currentProgress;
     26     String fileName = "QQPlayer.exe";
     27     //确定下载地址
     28     String path = "http://192.168.13.13:8080/" + fileName;
     29     private ProgressBar pb;
     30     TextView tv;
     31     
     32     Handler handler = new Handler(){
     33         public void handleMessage(android.os.Message msg) {
     34             //把变量改成long,在long下运算
     35             tv.setText((long)pb.getProgress() * 100 / pb.getMax() + "%");
     36         }
     37     };
     38     @Override
     39     protected void onCreate(Bundle savedInstanceState) {
     40         super.onCreate(savedInstanceState);
     41         setContentView(R.layout.activity_main);
     42         pb = (ProgressBar) findViewById(R.id.pb);
     43         tv = (TextView) findViewById(R.id.tv);
     44     }
     45 
     46     public void click(View v){
     47         
     48         Thread t = new Thread(){
     49             @Override
     50             public void run() {
     51                 //发送get请求,请求这个地址的资源
     52                 try {
     53                     URL url = new URL(path);
     54                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     55                     conn.setRequestMethod("GET");
     56                     conn.setConnectTimeout(5000);
     57                     conn.setReadTimeout(5000);
     58                     
     59                     if(conn.getResponseCode() == 200){
     60                         //拿到所请求资源文件的长度
     61                         int length = conn.getContentLength();
     62                         
     63                         //设置进度条的最大值就是原文件的总长度
     64                         pb.setMax(length);
     65                         
     66                         File file = new File(Environment.getExternalStorageDirectory(), fileName);
     67                         //生成临时文件
     68                         RandomAccessFile raf = new RandomAccessFile(file, "rwd");
     69                         //设置临时文件的大小
     70                         raf.setLength(length);
     71                         raf.close();
     72                         //计算出每个线程应该下载多少字节
     73                         int size = length / ThreadCount;
     74                         
     75                         for (int i = 0; i < ThreadCount; i++) {
     76                             //计算线程下载的开始位置和结束位置
     77                             int startIndex = i * size;
     78                             int endIndex = (i + 1) * size - 1;
     79                             //如果是最后一个线程,那么结束位置写死
     80                             if(i == ThreadCount - 1){
     81                                 endIndex = length - 1;
     82                             }
     83 //                            System.out.println("线程" + i + "的下载区间是:" + startIndex + "---" + endIndex);
     84                             new DownLoadThread(startIndex, endIndex, i).start();
     85                         }
     86                     }
     87                 } catch (Exception e) {
     88                     // TODO Auto-generated catch block
     89                     e.printStackTrace();
     90                 }
     91             }
     92         };
     93         t.start();
     94     }
     95     
     96     class DownLoadThread extends Thread{
     97         int startIndex;
     98         int endIndex;
     99         int threadId;
    100         
    101         public DownLoadThread(int startIndex, int endIndex, int threadId) {
    102             super();
    103             this.startIndex = startIndex;
    104             this.endIndex = endIndex;
    105             this.threadId = threadId;
    106         }
    107 
    108         @Override
    109         public void run() {
    110             //再次发送http请求,下载原文件
    111             try {
    112                 File progressFile = new File(Environment.getExternalStorageDirectory(), threadId + ".txt");
    113                 //判断进度临时文件是否存在
    114                 if(progressFile.exists()){
    115                     FileInputStream fis = new FileInputStream(progressFile);
    116                     BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    117                     //从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置
    118                     int lastProgress = Integer.parseInt(br.readLine());
    119                     startIndex += lastProgress;
    120                     
    121                     //把上次下载的进度显示至进度条
    122                     currentProgress += lastProgress;
    123                     pb.setProgress(currentProgress);
    124                     
    125                     //发送消息,让主线程刷新文本进度
    126                     handler.sendEmptyMessage(1);
    127                     fis.close();
    128                 }
    129                 System.out.println("线程" + threadId + "的下载区间是:" + startIndex + "---" + endIndex);
    130                 HttpURLConnection conn;
    131                 URL url = new URL(path);
    132                 conn = (HttpURLConnection) url.openConnection();
    133                 conn.setRequestMethod("GET");
    134                 conn.setConnectTimeout(5000);
    135                 conn.setReadTimeout(5000);
    136                 //设置本次http请求所请求的数据的区间
    137                 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
    138                 
    139                 //请求部分数据,相应码是206
    140                 if(conn.getResponseCode() == 206){
    141                     //流里此时只有1/3原文件的数据
    142                     InputStream is = conn.getInputStream();
    143                     byte[] b = new byte[1024];
    144                     int len = 0;
    145                     int total = 0;
    146                     //拿到临时文件的输出流
    147                     File file = new File(Environment.getExternalStorageDirectory(), fileName);
    148                     RandomAccessFile raf = new RandomAccessFile(file, "rwd");
    149                     //把文件的写入位置移动至startIndex
    150                     raf.seek(startIndex);
    151                     while((len = is.read(b)) != -1){
    152                         //每次读取流里数据之后,同步把数据写入临时文件
    153                         raf.write(b, 0, len);
    154                         total += len;
    155                         System.out.println("线程" + threadId + "下载了" + total);
    156                         
    157                         //每次读取流里数据之后,把本次读取的数据的长度显示至进度条
    158                         currentProgress += len;
    159                         pb.setProgress(currentProgress);
    160                         //发送消息,让主线程刷新文本进度
    161                         handler.sendEmptyMessage(1);
    162                         
    163                         //生成一个专门用来记录下载进度的临时文件
    164                         RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");
    165                         //每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中
    166                         progressRaf.write((total + "").getBytes());
    167                         progressRaf.close();
    168                     }
    169                     System.out.println("线程" + threadId + "下载完毕-------------------小志参上!");
    170                     raf.close();
    171                     
    172                     finishedThread++;
    173                     synchronized (path) {
    174                         if(finishedThread == ThreadCount){
    175                             for (int i = 0; i < ThreadCount; i++) {
    176                                 File f = new File(Environment.getExternalStorageDirectory(), i + ".txt");
    177                                 f.delete();
    178                             }
    179                             finishedThread = 0;
    180                         }
    181                     }
    182                     
    183                 }
    184             } catch (Exception e) {
    185                 // TODO Auto-generated catch block
    186                 e.printStackTrace();
    187             }
    188         }
    189     }
    190 
    191 }
  • 相关阅读:
    使用Windows Live Writer发布日志
    下雪
    Oracle中拼出树型结构
    [转载]Javascript中最常用的55个经典技巧
    博客访问者来自15个国家和地区
    [转载]一个帐号同一时间只能一个人登录
    换了博客的皮肤
    常见的开源软件许可
    java5中的Arrays
    青花瓷
  • 原文地址:https://www.cnblogs.com/liyiran/p/5062128.html
Copyright © 2011-2022 走看看