• 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();
                }
            }
        }
    
    }
  • 相关阅读:
    Ex 6_20 最优二叉搜索树..._第六次作业
    Ex 6_12 凸多边形的最优三角剖分..._第六次作业
    Ex 6_9 某个字符串处理语言提供了一个将字符串一分为二的基本操作..._第六次作业
    Ex 6_4 判断序列是否由合法单词组成..._第六次作业
    maven配置阿里云镜像时(私服设置~JEECG)
    node、npm、webpack、vue-cli傻傻分不清?
    设计模式~观察者模式和发布订阅模式的比较:
    前端~定位属性position(relative、absolute、fixed)的分析
    debounce防抖函数减少函数调用的逻辑分析(包裹上时间的外衣,在时间还没来时,kill)
    js原生滚动与使用插件better-scroll不起作用原因
  • 原文地址:https://www.cnblogs.com/84126858jmz/p/4966730.html
Copyright © 2020-2023  润新知