zoukankan      html  css  js  c++  java
  • android加了进度条和进度文本多线程断点续传下载

    我们要用进度条首先要改变它的样式,变成水平的

      <ProgressBar
            android:id="@+id/pro"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/Widget.ProgressBar.Horizontal" 
            />

    更新进度条不需要handle

    然后我们要在三个地方设置进度条,首先要在第一次请求长度的时候设置进度条的最大值pro.setMax(length);

    然后在下载的时候把每次的进度加起来,然后设置当前进度pro.setProgress(progress);

    最后要实现断点续传读取进度文件里的时候设置进度,为了就是断了之后进度条能够更新;

    文本进度条要用textview来实现,更新它就需要用handle来更新了

    package com.example.threaddownload;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.app.Activity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
        private static String path = "http://192.168.21.1:8080/ok/TGPSetup.exe";
        private static int threadCount = 3;
        private static int finishThread = 0;
        //添加进度条
        private ProgressBar pro;
        //进度数
        private int progress;
        //添加文本进度
        private TextView tv;
        private Handler handler = new Handler(){
            public void handleMessage(android.os.Message msg) {
                //如果有的时候下载的文件过大会出现负数改成long表示就可以了
                tv.setText((long)pro.getProgress()*100/pro.getMax()+"%");
            
            };
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            pro = (ProgressBar) findViewById(R.id.pro);
            tv = (TextView) findViewById(R.id.tv);
            findViewById(R.id.start).setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    new Thread() {
                        @Override
                        public void run() {
    
                            try {
                                URL url = new URL(path);
                                HttpURLConnection conn = (HttpURLConnection) url
                                        .openConnection();
                                conn.setRequestMethod("GET");
                                conn.setReadTimeout(5000);
                                conn.setConnectTimeout(5000);
                                if (conn.getResponseCode() == 200) {
                                    // 第一次请求要下载的长度
                                    int length = conn.getContentLength();
                                    
                                    pro.setMax(length);
                                    //给主线程发送消息
                                    handler.sendEmptyMessage(1);
                                    // 应该从字符串中截取文件名称
                                    File file = new File(Environment.getExternalStorageDirectory(),"TGPSetup.exe");
                                    // 在下载之前生成临时文件,占位置
                                    RandomAccessFile rdm = new RandomAccessFile(
                                            file, "rwd");
                                    // 给临时文件大小
                                    rdm.setLength(length);
                                    // 关闭
                                    rdm.close();
                                    // 计算每个线程应该下载的长度
                                    int size = length / threadCount;
                                    // 为每个线程分配开始位置和结束位置
                                    for (int i = 0; i < threadCount; i++) {
                                        int start = i * size;
                                        int end = (i + 1) * size - 1;
                                        // 最后一个线程的结束位置为总长度
                                        if (i == threadCount - 1) {
                                            end = length;
                                        }
                                        // 每次都调用新的线程
                                        new DownThread(start, end, i).start();
                                    }
                                }
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
    
                        }
                    }.start();
    
                }
            });
    
        }
    
        // 线程
        class DownThread extends Thread {
            private int start;
            private int end;
            private int threadId;
    
            public DownThread(int start, int end, int threadId) {
                this.start = start;
                this.end = end;
                this.threadId = threadId;
            }
    
            @Override
            public void run() {
                try {
                    // 创建进度文件
                    File progressFile = new File(Environment.getExternalStorageDirectory(),threadId + ".txt");
                    // 判断是否有记录进度的文件,如果有的话把开始位置重新赋值
                    if (progressFile.exists()) {
                        FileInputStream fis = new FileInputStream(progressFile);
                        BufferedReader br = new BufferedReader(
                                new InputStreamReader(fis));
                        int lastProgress =Integer.parseInt(br.readLine()); 
                        start += lastProgress;
                        //上次下载的显示到进度条
                        progress+=lastProgress;
                        pro.setProgress(progress);
                        
                        fis.close();
    
                    }
                    System.out.println(threadId + "线程下载区间" + start + "---" + end);
                    // 再次请求网络
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url
                            .openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(5000);
                    conn.setConnectTimeout(5000);
                    // 设置本次请求的文件的长度
                    conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
                    // 请求部分数据是206
                    if (conn.getResponseCode() == 206) {
                        // 得到请求长度的文件输入流
                        InputStream is = conn.getInputStream();
                        byte[] b = new byte[1024];
                        int len = 0;
                        // 记录每一次下载字节数
                        int totle = 0;
                    
                        // 应该从字符串中截取文件名称
                        File file = new File(Environment.getExternalStorageDirectory(),"TGPSetup.exe");
                        // 拿到之前占位置那个文件,相当于输出流
                        RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
                        // 改变写入文件的开始位置
                        rdm.seek(start);
                        while ((len = is.read(b)) != -1) {
                            // 每次读取流里的数据写到临时文件里
                            rdm.write(b, 0, len);
                            totle += len;
                            progress+=len;
                            handler.sendEmptyMessage(1);
                            pro.setProgress(progress);
                            System.out.println(threadId + "线程" + "下载了" + totle);
                            // 把下载的总数存到进度文件里
                            RandomAccessFile rdm1 = new RandomAccessFile(
                                    progressFile, "rwd");
                            rdm1.write((totle + "").getBytes());
                            rdm1.close();
                        }
                        rdm.close();
                        finishThread++;
                        // 下载结束删除进度文件
                        if (finishThread == threadCount) {
                            // 加同步锁
                            synchronized (path) {
                                for (int i = 0; i < threadCount; i++) {
                                    File f = new File(Environment.getExternalStorageDirectory(),i + ".txt");
                                    f.delete();
                                }
                                finishThread = 0;
                            }
                        }
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
  • 相关阅读:
    POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
    LCA 最近公共祖先 (模板)
    线段树,最大值查询位置
    带权并查集
    转负二进制
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
  • 原文地址:https://www.cnblogs.com/84126858jmz/p/4966730.html
Copyright © 2011-2022 走看看