【Android基礎知識】Android多線程下載

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章