多线程断点续传

public class DownLoadFile {

private final int SUCCESS = 0x00000101;
private final int FAILURE = 0x00000102;

private Handler handler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        if (downLoadListener != null) {
            if (msg.what == SUCCESS) {
                downLoadListener.onComplete();
            } else if (msg.what == FAILURE) {

            } else {
                downLoadListener.getProgress(msg.what);
            }
        }
    }
};

private static final String sp_name = "download_file";
private static final String curr_lenth = "curr_lenth";

private static final String down_init = "1";
private static final String down_ing = "2";
private static final String down_pause = "3";

private Context mcontext;

private String loadUrl;
private String filePath;

private int thread_count;

private int fileLenth;

private volatile int currLength;
private volatile int runningThreadCount;

private Thread[] mthreads;
private String stateDownload = down_init;

private DownLoadListener downLoadListener;

public DownLoadFile(Context mcontext, String loadUrl, String filePath, DownLoadListener downLoadListener) {
    this.mcontext = mcontext;
    this.loadUrl = loadUrl;
    this.filePath = filePath;
    thread_count = 3;
    runningThreadCount = 0;
    this.downLoadListener = downLoadListener;
}

public void play() {

    new Thread(new Runnable() {
        @Override
        public void run() {

            try {

                if (mthreads == null)
                    mthreads = new Thread[thread_count];

                URL url = new URL(loadUrl);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setConnectTimeout(10000);
                urlConnection.setReadTimeout(10000);

                int responseCode = urlConnection.getResponseCode();
                if (responseCode == 200) {

                    fileLenth = urlConnection.getContentLength();
                    RandomAccessFile rwd = new RandomAccessFile(filePath, "rwd");

                    rwd.setLength(fileLenth);
                    rwd.close();

                    int avg = fileLenth / thread_count;

                    SharedPreferences sp = mcontext.getSharedPreferences(sp_name, Context.MODE_PRIVATE);
                    currLength = sp.getInt(curr_lenth, 0);

                    for (int i = 0; i < thread_count; i++) {
                        int startPosition = sp.getInt(sp_name + i, i * avg);
                        int endPosition = (i + 1) * avg - 1;

                        if (i == thread_count - 1) {
                            endPosition = endPosition + thread_count;
                        }

                        mthreads[i] = new DownThread(i, startPosition, endPosition);
                        mthreads[i].start();
                    }

                } else {
                    handler.sendEmptyMessage(FAILURE);
                }

            } catch (Exception e) {
                handler.sendEmptyMessage(FAILURE);
            }

        }
    }).start();

}

public class DownThread extends Thread {

    private boolean isGoOn = true;//是否继续下载
    private int threadId;
    private int startPosition;//开始下载点
    private int endPosition;//结束下载点
    private int currPosition;

    private DownThread(int threadId, int startPosition, int endPosition) {
        this.threadId = threadId;
        this.startPosition = startPosition;
        currPosition = startPosition;
        this.endPosition = endPosition;
        runningThreadCount++;//正在运行的线程数
    }

    @Override
    public void run() {
        SharedPreferences sp = mcontext.getSharedPreferences(sp_name, Context.MODE_PRIVATE);
        try {
            URL url = new URL(loadUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);
            conn.setConnectTimeout(5000);
            int responseCode = conn.getResponseCode();
            if (responseCode == 206) {

                InputStream inputStream = conn.getInputStream();
                RandomAccessFile raw = new RandomAccessFile(filePath, "rwd");
                raw.seek(startPosition);
                int len;
                byte[] bytes = new byte[1024];

                while ((len = inputStream.read(bytes)) != -1) {

                    raw.write(bytes, 0, len);

                    if (downLoadListener != null) {
                        currLength += len;
                        int progress = (int) ((float) currLength / (float) fileLenth * 100);
                        handler.sendEmptyMessage(progress);
                    }

                    synchronized ("sss") {
                        if (stateDownload.equals(down_pause)) {
                            "sss".wait();
                        }
                    }

                }

                inputStream.close();
                raw.close();

                runningThreadCount--;

                if (runningThreadCount == 0) {
                    sp.edit().clear().apply();
                    handler.sendEmptyMessage(SUCCESS);
                    handler.sendEmptyMessage(100);
                    mthreads = null;
                }


            }

        } catch (Exception e) {

        }
    }

}
public void onPause() {
    if (mthreads != null)
        stateDownload = down_pause;
}

public void onStart() {
    if (mthreads != null)
        synchronized ("sss") {
            stateDownload = down_ing;
            "sss".notifyAll();
        }
}

}

public interface DownLoadListener {

void getProgress(int progress);

void onComplete();

void onError();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值