zoukankan      html  css  js  c++  java
  • 33、多线程断点下载的实现&界面的更新

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="fill_parent"
     4     android:layout_height="fill_parent"
     5     android:orientation="vertical" >
     6 
     7     <TextView
     8         android:layout_width="fill_parent"
     9         android:layout_height="wrap_content"
    10         android:text="@string/down_load" />
    11 
    12     <EditText
    13         android:id="@+id/et"
    14         android:layout_width="fill_parent"
    15         android:layout_height="wrap_content"
    16         android:hint="@string/hint"
    17         android:text="http://192.168.1.247:8080/youdao.exe" />
    18 
    19     <ProgressBar
    20         android:id="@+id/pb"
    21         style="?android:attr/progressBarStyleHorizontal"
    22         android:layout_width="fill_parent"
    23         android:layout_height="wrap_content" />
    24 
    25     <TextView
    26         android:id="@+id/tv_process"
    27         android:layout_width="fill_parent"
    28         android:layout_height="wrap_content" />
    29 
    30     <Button
    31         android:id="@+id/bt"
    32         android:layout_width="fill_parent"
    33         android:layout_height="wrap_content"
    34         android:text="@string/download" />
    35 
    36 </LinearLayout>
      1 /**
      2  * 49_多线程断点下载的实现&界面的更新 DEMO
      3  * @author dr
      4  *
      5  */
      6 public class DemoActivity extends Activity implements OnClickListener {
      7 
      8     private ProgressBar pb;
      9     private Button bt;
     10     private TextView tv;
     11     private EditText et;
     12     boolean flag = true;
     13     boolean stopflag = false;
     14     int total = 0;
     15 
     16     private Handler handler = new Handler() {
     17 
     18         @Override
     19         public void handleMessage(Message msg) {
     20             pb.setProgress(total);
     21             // 文件总长度
     22             int max = pb.getMax();  
     23             // total和max都是从0开始的。
     24             if (total >= (max - 1)) { 
     25                 total = max;
     26                 flag = false;
     27             }
     28             int result = total * 100 / max;
     29             tv.setText("当前进度 :" + result + "%");
     30 
     31             super.handleMessage(msg);
     32         }
     33     };
     34 
     35     @Override
     36     public void onCreate(Bundle savedInstanceState) {
     37         super.onCreate(savedInstanceState);
     38         setContentView(R.layout.main);
     39         pb = (ProgressBar) this.findViewById(R.id.pb);
     40         bt = (Button) this.findViewById(R.id.bt);
     41         tv = (TextView) this.findViewById(R.id.tv_process);
     42         et = (EditText) this.findViewById(R.id.et);
     43         bt.setOnClickListener(this);
     44 
     45     }
     46 
     47     @Override
     48     public void onClick(View v) {
     49         switch (v.getId()) {
     50         case R.id.bt:
     51             // 创建一个子线程 定期的更新ui
     52             if ("开始下载".equals(bt.getText().toString())) {
     53                 bt.setText("暂停");
     54                 stopflag = false; // 开始下载
     55             } else {
     56                 bt.setText("开始下载");
     57                 stopflag = true;
     58             }
     59             new Thread() {
     60                 @Override
     61                 public void run() {
     62                     super.run();
     63                     while (flag) {
     64                         try {
     65                             sleep(1000);
     66                             // 如果total > = 文件长度
     67                             Message msg = new Message();
     68                             handler.sendMessage(msg);
     69                         } catch (InterruptedException e) {
     70                             e.printStackTrace();
     71                         }
     72                     }
     73                 }
     74             }.start();
     75 
     76             // 开始执行下载的操作
     77             String path = et.getText().toString().trim();
     78             if ("".equals(path)) {
     79                 Toast.makeText(this, "路径不能为空", 1).show();
     80                 return;
     81             }
     82             try {
     83                 URL url = new URL(path);
     84                 HttpURLConnection conn = (HttpURLConnection) url
     85                         .openConnection();
     86                 conn.setRequestMethod("GET");
     87                 conn.setConnectTimeout(5000);
     88                 conn.setRequestProperty("User-Agent",
     89                         "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
     90                 int code = conn.getResponseCode();
     91                 if (code == 200) {
     92                     int len = conn.getContentLength();
     93                     RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/"
     94                             + getFilenName(path), "rwd");
     95                     // 1.设置本地文件大小跟服务器的文件大小一致
     96                     file.setLength(len);
     97                     // 设置进度条的最大值
     98                     pb.setMax(len);
     99 
    100                     // 2 .假设开启3 个线程
    101                     int threadnumber = 3;
    102                     int blocksize = len / threadnumber;
    103                     /**
    104                      * 线程1 0~ blocksize 线程2 1*bolocksize ~ 2*blocksize 线程3
    105                      * 2*blocksize ~ 文件末尾
    106                      */
    107                     for (int i = 0; i < threadnumber; i++) {
    108                         int startposition = i * blocksize;
    109                         int endpositon = (i + 1) * blocksize;
    110                         if (i == (threadnumber - 1)) {
    111                             // 最后一个线程
    112                             endpositon = len;
    113                         }
    114 
    115                         DownLoadTask task = new DownLoadTask(i, path,
    116                                 startposition, endpositon);
    117                         task.start();
    118                     }
    119 
    120                 }
    121             } catch (Exception e) {
    122                 Toast.makeText(this, "下载出现异常", 0).show();
    123                 e.printStackTrace();
    124             }
    125 
    126             break;
    127         }
    128 
    129     }
    130 
    131     class DownLoadTask extends Thread {
    132 
    133         int threadid;
    134         String filepath;
    135         int startposition;
    136         int endpositon;
    137 
    138         public DownLoadTask(int threadid, String filepath, int startposition,
    139                 int endpositon) {
    140             this.threadid = threadid;
    141             this.filepath = filepath;
    142             this.startposition = startposition;
    143             this.endpositon = endpositon;
    144 
    145         }
    146 
    147         @Override
    148         public void run() {
    149             try {
    150               File postionfile = new File("/mnt/sdcard/" + threadid + ".txt");
    151                 URL url = new URL(filepath);
    152                 HttpURLConnection conn = (HttpURLConnection) url
    153                         .openConnection();
    154                 System.out.println("线程" + threadid + "正在下载 " + "开始位置 : "
    155                         + startposition + "结束位置 " + endpositon);
    156 
    157                 if (postionfile.exists()) {
    158                     FileInputStream fis = new FileInputStream(postionfile);
    159                     byte[] result = StreamTool.getBytes(fis);
    160                     String str = new String(result);
    161                     if (!"".equals(str)) {
    162                         int newstartposition = Integer.parseInt(str);
    163                         if (newstartposition > startposition) {
    164                             startposition = newstartposition;
    165                         }
    166                     }
    167                 }
    168 
    169                 // "Range", "bytes=2097152-4194303")
    170                 conn.setRequestProperty("Range", "bytes=" + startposition + "-"
    171                         + endpositon);
    172                 conn.setRequestMethod("GET");
    173                 conn.setConnectTimeout(5000);
    174                 conn.setRequestProperty("User-Agent",
    175                         "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    176                 InputStream is = conn.getInputStream();
    177                 RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/"
    178                         + getFilenName(filepath), "rwd");
    179                 // 设置 数据从文件哪个位置开始写
    180                 file.seek(startposition);
    181                 byte[] buffer = new byte[1024];
    182                 int len = 0;
    183                 // 代表当前读到的服务器数据的位置 ,同时这个值已经存储的文件的位置
    184                 int currentPostion = startposition;
    185                 // 创建一个文件对象 ,记录当前某个文件的下载位置
    186 
    187                 while ((len = is.read(buffer)) != -1) {
    188                     if (stopflag) {   // 暂停下载
    189                         return;
    190                     }
    191                     file.write(buffer, 0, len);
    192 
    193                     synchronized (DemoActivity.this) { // 同步当前的
    194                         total += len;
    195                     }
    196 
    197                     currentPostion += len;
    198                     // 需要把currentPostion 信息给持久化到存储设备
    199                     String position = currentPostion + "";
    200                     FileOutputStream fos = new FileOutputStream(postionfile);
    201                     fos.write(position.getBytes());
    202                     fos.flush();
    203                     fos.close();
    204                 }
    205 
    206                 file.close();
    207                 System.out.println("线程" + threadid + "下载完毕");
    208                 // 当线程下载完毕后 把文件删除掉
    209                 if (postionfile.exists()) {
    210                     postionfile.delete();
    211                 }
    212             } catch (Exception e) {
    213                 e.printStackTrace();
    214             }
    215             super.run();
    216         }
    217     }
    218 
    219     public String getFilenName(String path) {
    220         int start = path.lastIndexOf("/") + 1;
    221         return path.substring(start, path.length());
    222     }
    223 }
     1 public class StreamTool {
     2     /**
     3      * 把一个inputstream里面的内容转化成一个byte[] 
     4      */
     5     public static byte[] getBytes(InputStream is) throws Exception{
     6         ByteArrayOutputStream bos = new ByteArrayOutputStream();
     7         byte[] buffer = new byte[1024];
     8         int len = 0;
     9         while((len = is.read(buffer))!=-1){
    10             bos.write(buffer, 0, len);
    11         }
    12         is.close();
    13         bos.flush();
    14         byte[] result = bos.toByteArray();
    15         System.out.println(new String(result));
    16         return  result;
    17     }
    18 }
    1     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    2     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    3     <uses-permission android:name="android.permission.INTERNET"/>

  • 相关阅读:
    ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    Linux学习安装
    linux中的虚拟环境工具
    linux 文件目录权限
    PHP利用百度ai实现文本和图片审核
    Laravel + Swoole 打造IM简易聊天室
    Mysql索引降维 优化查询 提高效率
    Nginx支持比Apache高并发的原因
    网站高并发解决方案(理论知识)
    mysql大量数据分页查询优化-延迟关联
  • 原文地址:https://www.cnblogs.com/androidsj/p/3966258.html
Copyright © 2011-2022 走看看