多线程下载断点续传

来源:互联网 发布:vip视频解析源码heml 编辑:程序博客网 时间:2024/05/16 18:34
package com.itheima.multithreaddownload;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.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity {    String path = "http://169.254.244.136:8080/QQPlayer.exe";    int threadCount = 3;    int finishedThread = 0;    //所有线程下载总进度    int downloadProgress = 0;    private ProgressBar pb;    private TextView tv;    Handler handler = new Handler(){        public void handleMessage(android.os.Message msg) {            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(){            @Override            public void run() {                //发送http请求,拿到目标文件长度                try {                    URL url = new URL(path);                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();                    conn.setRequestMethod("GET");                    conn.setConnectTimeout(8000);                    conn.setReadTimeout(8000);                    if(conn.getResponseCode() == 200){                        //获取长度                        int length = conn.getContentLength();                        //创建临时文件                        File file = new File(Environment.getExternalStorageDirectory(), getNameFromPath(path));                        RandomAccessFile raf = new RandomAccessFile(file, "rwd");                        //设置临时文件大小与目标文件一致                        raf.setLength(length);                        raf.close();                        //设置进度条的最大值                        pb.setMax(length);                        //计算每个线程下载区间                        int size = length / threadCount;                        for (int id = 0; id < threadCount; id++) {                            //计算每个线程下载的开始位置和结束位置                            int startIndex = id * size;                            int endIndex = (id + 1) * size - 1;                            if(id == threadCount - 1){                                endIndex = length - 1;                            }                            System.out.println("线程" + id + "下载的区间:" + startIndex + " ~ " + endIndex);                            new DownLoadThread(id, startIndex, endIndex).start();                        }                    }                } catch (Exception e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        };        t.start();    }    public String getNameFromPath(String path){        int index = path.lastIndexOf("/");        return path.substring(index + 1);    }    class DownLoadThread extends Thread{        int threadId;        int startIndex;        int endIndex;        public DownLoadThread(int threadId, int startIndex, int endIndex) {            super();            this.threadId = threadId;            this.startIndex = startIndex;            this.endIndex = endIndex;        }        @Override        public void run() {            try {                File fileProgress = new File(Environment.getExternalStorageDirectory(), threadId + ".txt");                int lastProgress = 0;                if(fileProgress.exists()){                    //读取进度临时文件中的内容                    FileInputStream fis = new FileInputStream(fileProgress);                    BufferedReader br = new BufferedReader(new InputStreamReader(fis));                    //得到上一次下载进度                    lastProgress = Integer.parseInt(br.readLine());                    //改变下载的开始位置,上一次下过的,这次就不请求了                    startIndex += lastProgress;                    fis.close();                    //把上一次下载进度加到进度条进度中                    downloadProgress += lastProgress;                    pb.setProgress(downloadProgress);                    //发送消息,让文本进度条改变                    handler.sendEmptyMessage(1);                }                //发送http请求,请求要下载的数据                URL url = new URL(path);                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setRequestMethod("GET");                conn.setConnectTimeout(8000);                conn.setReadTimeout(8000);                //设置请求数据的区间                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);                //请求部分数据,成功的响应码是206                if(conn.getResponseCode() == 206){                    InputStream is = conn.getInputStream();                    byte[] b = new byte[1024];                    int len = 0;                    //当前线程下载的总进度                    int total = lastProgress;                    File file = new File(Environment.getExternalStorageDirectory(), getNameFromPath(path));                    RandomAccessFile raf = new RandomAccessFile(file, "rwd");                    //设置写入的开始位置                    raf.seek(startIndex);                    while((len = is.read(b)) != -1){                        raf.write(b, 0, len);                        total += len;                        System.out.println("线程" + threadId + "下载了:" + total);                        //创建一个进度临时文件,保存下载进度                        RandomAccessFile rafProgress = new RandomAccessFile(fileProgress, "rwd");                        //每次下载1024个字节,就,就马上把1024写入进度临时文件                        rafProgress.write((total + "").getBytes());                        rafProgress.close();                        //每次下载len个长度的字节,马上把len加到下载进度中,让进度条能反应这len个长度的下载进度                        downloadProgress += len;                        pb.setProgress(downloadProgress);                        //发送消息,让文本进度条改变                        handler.sendEmptyMessage(1);                    }                    raf.close();                    System.out.println("线程" + threadId + "下载完毕------------------");                    //3条线程全部下载完毕,才去删除进度临时文件                    finishedThread++;                    synchronized (path) {                        if(finishedThread == threadCount){                            for (int i = 0; i < threadCount; i++) {                                File f = new File(Environment.getExternalStorageDirectory(), i + ".txt");                                f.delete();                            }                            finishedThread = 0;                        }                    }                }            }            catch (Exception e) {                e.printStackTrace();            }        }    }}
<?xml version="1.0"?>-<LinearLayout android:orientation="vertical" tools:context=".MainActivity" android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"><Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:onClick="click" android:text="下载"/><ProgressBar android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/pb" style="@android:style/Widget.ProgressBar.Horizontal"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="0%" android:id="@+id/tv" android:layout_gravity="right"/></LinearLayout>
<?xml version="1.0" encoding="UTF-8"?>-<manifest android:versionName="1.0" android:versionCode="1" package="com.itheima.multithreaddownload" xmlns:android="http://schemas.android.com/apk/res/android"><uses-sdk android:targetSdkVersion="17" android:minSdkVersion="8"/><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>-<application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:allowBackup="true">-<activity android:name="com.itheima.multithreaddownload.MainActivity" android:label="@string/app_name">-<intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
0 0
原创粉丝点击