使用Android 多線程進行下載,需要使用網絡操作,線程池,文件操作的知識,這裏自己搭建一個服務器,創建一個web工程,webroot下面放置一張圖片就可以了。
多線程下載 Download.java
public class Download {
private Handler handler;
public Download(Handler handler){
this.handler = handler;
}
//創建線程池
private Executor threadPool = Executors.newFixedThreadPool(3);
static class DownLoadRunnable implements Runnable{
private String url;
private String fileName;
//下載的起始位置
private long start;
//下載的結束位置
private long end;
private Handler handler;
public DownLoadRunnable(String url,String fileName,long start,long end,Handler handler){
this.url = url;
this.fileName = fileName;
this.start = start;
this.end = end;
this.handler = handler;
}
@Override
public void run() {
URL httpUrl;
try {
httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setReadTimeout(5000);
//設置下載的起始位置和結束位置,注意格式
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
conn.setRequestMethod("GET");
RandomAccessFile access = new RandomAccessFile(new File(fileName), "rwd");
//定位到文件的指定位置
access.seek(start);
InputStream in = conn.getInputStream();
byte[] b = new byte[4*1024];
int len = 0;
while((len = in.read(b))!= -1){
access.write(b,0,len);
}
if(access != null){
access.close();
}
if(in != null){
in.close();
}
//每個線程下載完成,使用handler向主線程發送一個消息
Message message = new Message();
message.what =1;
handler.sendMessage(message);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//下載
public void downLoadFile(String url){
try{
URL httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
//獲取要下載內容的長度
int count = conn.getContentLength();
//開啓了3個線程,所以總共分三塊下載
int block = count/3;
//獲取下載文件的名字
String fileName = getNameFromUrl(url);
File parent = Environment.getExternalStorageDirectory();
//創建一個文件
File imageFile = new File(parent,fileName);
//總共三個線程,啓動for循環向線程池提交任務
for(int i = 0;i<3;i++){
long start = i*block;
long end = (i+1)*block-1;
if(i ==2){
//最後一個處理多出來的字節,避免下載不全
end = count;
}
DownLoadRunnable runable = new DownLoadRunnable(url, imageFile.getAbsolutePath(), start, end,handler);
//通過線程池提交任務
threadPool.execute(runable);
}
}catch(MalformedURLException e){
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//取出url的後綴名
public String getNameFromUrl(String url){
return url.substring(url.lastIndexOf("/")+1);
}
}
調用類 MainActivity.java
public class MainActivity extends Activity {
private Button button;
private TextView textView;
private int count = 0;
private Handler handler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
//總共開啓了三個線程,如果收到了三個message,則說明下載成功
int result = msg.what;
count+= result;
if(count == 3){
textView.setText("downloadSuccess");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button1);
textView = (TextView)findViewById(R.id.text);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//網絡操作不能放在主線程,這裏開啓一個線程訪問網絡
new Thread(){
@Override
public void run() {
Download download = new Download(handler);
download.downLoadFile("http://192.168.199.126:8080/Server/image.jpg");
}
}.start();
}
});
}
}