import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import android.os.Environment;
import android.os.Handler;
import android.os.Message;
/**
* 多线程下载
* @author raid
*
*/
public class Download {
/**
* 创建一个线程池
*/
private Executor threadPool = Executors.newFixedThreadPool(3);
/**
* 接收一个Handler对象,用于获取下载进度
*/
private Handler handler;
/**
* 默认的下载线程个数为3
*/
public static final int THREAD_COUNT = 3;

public Download(Handler handler) {
super();
this.handler = handler;
}

/**
* 下载线程,这里定义成静态类
* @author raid
*
*/
static class DownLoadRunnable implements Runnable {
private String url;
private String fileName;
private long start;
private long end;
private Handler handler;


/**
* 构造方法
* @param url 需要下载的网站url
* @param fileName 下载回本地的文件名
* @param start 开始位置
* @param end 终止位置
* @param handler 用于更新UI显示下载进度
*/
public DownLoadRunnable(String url, String fileName, long start,
long end, Handler handler) {
super();
this.url = url;
this.fileName = fileName;
this.start = start;
this.end = end;
this.handler = handler;
}



@Override
public void run() {
// TODO Auto-generated method stub
RandomAccessFile access = null;
InputStream in = null;
try {
HttpURLConnection conn = getConnection(url);
//设置请求读取文件的开始字节数和结束字节数
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
access = new RandomAccessFile(fileName, "rwd");
access.seek(start);
in = conn.getInputStream();
byte[] b = new byte[4*1024];
int len = 0;
while((len=in.read(b)) != -1) {
access.write(b, 0, len);
}

Message msg = Message.obtain();
msg.what = 1;
handler.sendMessage(msg);

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (access != null) {
try {
access.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}

/**
* 调用多线程下载的方法
* @param url 下载的资源的地址
*/
public void downloadFile(String url) {
HttpURLConnection conn = getConnection(url);
int count = conn.getContentLength();
int block = count / THREAD_COUNT;

String fileName = getFileName(url);
File parent = Environment.getExternalStorageDirectory();
File fileDownload = new File(parent, fileName);
for(int i = 0; i < THREAD_COUNT; i++) {
long start = i*block;
long end = (i+1) * block - 1;
if (i == THREAD_COUNT-1) {
end = count;
}
DownLoadRunnable runnable =
new DownLoadRunnable(url,
fileDownload.getAbsolutePath(),
start, end, handler);
threadPool.execute(runnable);
}
}

private String getFileName(String url) {
return url.substring(url.lastIndexOf("/")+1);
}

private static HttpURLConnection getConnection(String url) {
URL httpUrl;
try {
httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");

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

return null;
}
}