Http通信模仿迅雷多线程下载

用到的知识点:

1.Http 协议字段"Range", "bytes="+start+"-"+end

2.RandomAccessFile设置写入的位置

3.开启线程发送网络请求以及线程池操作


首先,在服务器端放一张图片,如下在WebRoot下放置了一张lufei.jpg图片

Http通信模仿迅雷多线程下载_第1张图片

跟访问网页一样通过url直接访问:http://pc-20141102midc:8080/DownLoadFile/lufei.jpg

然后在Android端写多线程下载的代码:

为了防止遗忘现在配置文件中声明权限:

  <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.download_file.MainActivity" >

    <Button
        android:id="@+id/start_download_bt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载"
        android:textColor="@android:color/background_dark" />

    <TextView
        android:id="@+id/my_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

下载类:

DownLoad.java

package com.example.download_file;

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.URL;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import android.os.Environment;
import android.os.Handler;
import android.os.Message;

/**
 * 多线程下载例子
 * @author weichongchong
 *
 */
public class DownLoad {
	private Handler mHandler;
	public DownLoad(Handler handle){
		this.mHandler= handle;
	}

	//通过线程池下载,创建线程池对象
	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() {
			// TODO Auto-generated method stub

			try {
				URL 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[1024*4];
				int len=0;
				while((len = in.read())!=-1){
					access.write(b,0,len);
				}
				if(access!=null){
					access.close();
				}
				if(in!=null){
					in.close();
				}
				//下载完成通知更新UI
				Message message = new  Message();
				message.what=1;
				handler.sendMessage(message);
				//				int count = conn.getContentLength();//拿到下载对象的长度
				//				int block = count/3;//平均到每个线程池
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				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();//拿到下载对象的长度
			int block = count/3;//平均到每个线程池
			String fileName = getFileName(url);
//			File parent = Environment.getExternalStorageDirectory();
//			File fileDownLoad = new File(parent,fileName);
			File fileDownLoad  = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),fileName);
			/**
			 * 11/3  3
			 * 第一个线程0-2
			 * 第二个3-5
			 * 第三个6-10
			 */

			for(int i=0;i<3;i++){
				long start = i*block;
				long end = (i+1)*block-1;
				if(i==2){
					end=count;
				}
				DownLoadRunnable runnable = new DownLoadRunnable(url,fileDownLoad.getAbsolutePath(),start,end,mHandler);
				threadPool.execute(runnable);//通过线程池提交任务
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}
	/**
	 * 
	 * @return
	 * 得到url后缀名,即文件名
	 */
	public String getFileName(String url){
		return url.substring(url.lastIndexOf("/")+1);
	}
}

MainActivity中代码使用下载类进行下载

package com.example.download_file;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {

	private Button start_download_bt;
	private TextView mytv;
	private int count = 0;

	private Handler mHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			int result = msg.what;
			count+=result;//如果三个线程都下载完成,都返回一个1,相加为3
			if(count==3){
				mytv.setText("下载完成");
				start_download_bt.setText("下载完成");
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		start_download_bt = (Button) findViewById(R.id.start_download_bt);
		mytv = (TextView) findViewById(R.id.my_tv);

		start_download_bt.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub

				start_download_bt.setText("正在下载");
				Toast.makeText(MainActivity.this, "正在下载", 0).show();
				
				
				new Thread(){
					@Override
					public void run() {
						// TODO Auto-generated method stub

						DownLoad mDownLoad  = new DownLoad(mHandler);
						mDownLoad.downLoadFile("http://192.168.1.105:8080/DownLoadFile/lufei.jpg");
					}
				}.start();

			}
		});
	}
}



你可能感兴趣的:(Http通信模仿迅雷多线程下载)