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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值