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();
}