网络下载,配上进度条

来源:互联网 发布:软件出现乱码怎么办 编辑:程序博客网 时间:2024/05/29 05:11
注意事项:我们知道加载进度,快慢是因为加载文件中,间隔二个,三个,五个,中间在写入刷新进度条,通常不每个都写入按照for循环的处理方式,那样虽然会非常的平滑,速度均匀,但是没有太大的一个意义,从用户使用体验上来说,并不会价值。

位置我用。11111已经标识出来了,注意观察。


public class MainActivity extends Activity {
      static int ThreadCount = 3;
      static int finishedThread= 0;

      int currentProgress;

      String fileName = "TakeColor.exe";
      //确定下载地址
      String path = "http://192.168.6.136:8080/" + fileName;
    private ProgressBar pb;
    TextView tv;

    Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            //把变量改成long,在long下运算,运算时候不会出现负值
              tv.setText((long)pb.getProgress() *100/pb.getMax()+"%");
        }
    };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = (ProgressBar) findViewById(R.id.pb);
        tv = (TextView) findViewById(R.id.tv);
    }

    public void click(View v){
        Thread t = new Thread(){
            public void run() {
                 try {
                        URL url = new URL(path);
                        HttpURLConnection conn =(HttpURLConnection) url.openConnection();
                        conn.setRequestMethod("GET");
                        conn.setConnectTimeout(5000);
                        conn.setReadTimeout(5000);

                        if(conn.getResponseCode()==200){
                            //拿到所请求文件的大小
                        int length = conn.getContentLength();
                        //设置进度条的最大值就是原文件的总长度
                        pb.setMax(length);

                        File file = new File(Environment.getExternalStorageDirectory(),fileName);
                        //生存临时文件
                        RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                        //设置临时文件的大小
                        raf.setLength(length);
                        raf.close();
                        //计算出每个线程应该下载多少字节
                        int size =length / ThreadCount;

11111                        for(int i =0;i<ThreadCount;i++){
                            //计算线程开始和结束的下载位置
                            int startIndex = i * size;
                            int endIndex = (i + 1) * size - 1;
                            //如果是最后一个线程,那么结束的位置写死
                            if(i==ThreadCount-1){
                                endIndex = length-1;
                            }
                            System.out.println("线程" + i +"的下载区间是:" +startIndex + "---" + endIndex);
                            new DownLoadThread(startIndex,endIndex,i).start();
                          }
                        } 
                      }catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                   }

        };
        t.start();
    }

class DownLoadThread extends Thread{
       int startIndex;
       int endIndex;
       int threadId;
       public DownLoadThread(int startIndex,int endIndex,int threadId){
           super();
            this.startIndex=startIndex;
            this.endIndex=endIndex;
            this.threadId=threadId;
       }

        public void run() {

            // TODO Auto-generated method stub
            //再次发送http请求,下载原文件
            HttpURLConnection conn;
            try {
                File progressFile = new File(Environment.getExternalStorageDirectory(),threadId +".text");
                //判断进度临时问价是否存在
                if(progressFile.exists()){
                    FileInputStream fis = new FileInputStream(progressFile);
                    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

                    //从进度临时文件中读取上一次临时文件下载的总进度,然后与原本的开始位置相加,得到新的开始位置
                    int lastProgress =Integer.parseInt(br.readLine()) ;
                    startIndex +=lastProgress;

                    //把上次下载的进度显示到进度条里面
                    currentProgress += lastProgress;
                    pb.setProgress(currentProgress);

                    //发送消息让主线程刷新文本进度
                    handler.sendEmptyMessage(1);
                    fis.close();
                }

                URL url = new URL(path);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                //设置本次http请求所请求的数据的区间
                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);

                //请求部分数据,响应码是206
                 if(conn.getResponseCode()==206){
                     //流里此时只有1/3原文件的数据
                    InputStream is = conn.getInputStream();
                    byte[] b= new byte[1024];
                    int len =0;
                    int total=0;
                    //拿到临时文件的输出流
                     File file = new File(Environment.getExternalStorageDirectory(),fileName);
                     //生存临时文件
                     RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                     //把文件的写入位置移动至startIndex
                     raf.seek(startIndex);
                     while((len = is.read(b))!=-1){
                         raf.write(b, 0, len);
                         total +=len;
                         System.out.println("线程" +threadId +"下载了" +total);
                         currentProgress +=len;
                         pb.setProgress(currentProgress);    


                         //发送消息让主线程刷新文本进度
                         handler.sendEmptyMessage(1);

                         //生成一个专门用来记录下载进度的临时文件
                         RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");
                         //每次读取流里的数据之后,同步把当前线程的总进度写进临时文件中
                         progressRaf.write((total+"").getBytes());
                         progressRaf.close();
                     }
                    raf.close();

                    finishedThread++;
                    synchronized (path) {
                        if(finishedThread ==ThreadCount){
                            for (int i = 0; i < ThreadCount; i++) {
                                File f = new File(Environment.getExternalStorageDirectory(),i + ".text");
                                f.delete();        
                            }
                            finishedThread = 0;

                        }

                    }

                 }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
 }
}


0 0