多线程下载和断点续传和进度条

public class MainActivity extends Activity {
	protected  final int DOWNLOAD_ERROR = 1;
	private  final int THREADE_ERROR = 2;
	private  final int DOWNLOAD_FINISH =3;
	private int threadcount;
	private long blocksize;
	private int threaddowncount = 3;
	EditText et_Path;
	EditText et_count;
	List<ProgressBar>pds=null;
	LinearLayout licontent;
	/**
	 * 安卓下的消息处理器
	 */
private Handler handler=new Handler(){
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case DOWNLOAD_ERROR:
			Toast.makeText(getApplicationContext(), "下载失败", 0).show();
			break;
	case THREADE_ERROR:
		Toast.makeText(getApplicationContext(), "下载进程出错", 0).show();
			break;
	case DOWNLOAD_FINISH:
		Toast.makeText(getApplicationContext(), "下载成功", 0).show();
		break;
		
		}
	};
};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		et_Path = (EditText) findViewById(R.id.fileurl);
		et_count=(EditText) findViewById(R.id.count);
		licontent=(LinearLayout) findViewById(R.id.ll_containt);
		
	}

	public void download(View view) {
		Toast.makeText(this, "开始下载", 0).show();
	     String etcount=et_count.getText().toString();
	     threaddowncount=Integer.valueOf(etcount);
	     licontent.removeAllViews();
	     pds=new ArrayList<ProgressBar>();
	     for (int i = 0; i < threaddowncount; i++) {
	    	 ProgressBar pd=(ProgressBar) view.inflate(this, R.layout.pd, null);
	    	 licontent.addView(pd);
	    	 pds.add(pd);
		}
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					String path = "http://192.168.0.101:8080/duoxianchengxiazai/Android.rar";// 定义下载文件地址
					URL url = new URL(path);// 利用url 开启下载
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();// 打开这个url获得一个连接
					conn.setReadTimeout(5000);// 设置超时时间
					conn.setRequestMethod("GET");// 设置请求方法 大写 get和psot两种
					int code = conn.getResponseCode();// 获得状态码 标示是否请求成功
					if (code == 200) {
						long size = conn.getContentLength();// 获得要下载文件的大小
						Log.i("文件大小", size + "");
						//threadcount = 3;// 定义下载的线程数量
						threadcount=threaddowncount;
						blocksize = size / threaddowncount;// 得到 一个线程需要下载的文件块大小
						// 首先在本地创建一个和下载文件一模一样大小的文件
						File sd=Environment.getExternalStorageDirectory();
				
						boolean bool=sd.canRead();
						File file = new File(Environment.getExternalStorageDirectory(),getfilename(path));
						RandomAccessFile ra = new RandomAccessFile(file, "rw");// rw
						// 如果没有就新建
						ra.setLength(size);// 设置本地文件大小
						// 开启若干个线程,分别去下载相对应的资源
						for (int i = 1; i <= threadcount; i++) {
							// long starindex = (i - 1) * blocksize + 1;
							// long endindex = i * blocksize;//本来是这样的
							// 因为服务器是从0开始而不是从1开始
							// 所以不可用
							long starindex = (i - 1) * blocksize + 0;
							long endindex = i * blocksize - 1;
							if (i == threadcount) {
								endindex = size - 1;
							}
							int max=(int)(endindex-starindex);
							pds.get(i-1).setMax(max);
							threaddownload th = new threaddownload(i,
									starindex, endindex, path);
							th.start();
						}
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Message msg=Message.obtain();
					msg.what=DOWNLOAD_ERROR;
					handler.sendMessage(msg);
				}
			}
		}).start();

	}

	/**
	 * 内部线程类
	 * 
	 * @author Administrator
	 * 
	 */
	public class threaddownload extends Thread {
		
		
		private int threadid;
		private long starindex;
		private long endindex;
		private String path;

		public threaddownload(int threadid, long starindex, long endindex,
				String path) {
			super();
			this.threadid = threadid;
			this.starindex = starindex;
			this.endindex = endindex;
			this.path = path;

		}

		// 重写父类run方法
		public void run() {
			try {
				int total = 0;// 断电续传加的代码 定义 下载多少
				File fileinfo = new File( Environment.getExternalStorageDirectory(),threadid + ".txt");// 断点续传加的代码
				// 定义已经下载的保存文件

				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection) url
						.openConnection();
				conn.setReadTimeout(5000);
				conn.setRequestMethod("GET");

				// 这里是断点续传操作 需要在这里接着上次下载的大小开始下载
				if (fileinfo.exists() && fileinfo.length() > 0) {
					FileInputStream fs = new FileInputStream(fileinfo);
					BufferedReader buff = new BufferedReader(
							new InputStreamReader(fs));
					// 获得上次下载的大小
					String lasttoalstr = buff.readLine();
					int lasttotal = Integer.parseInt(lasttoalstr);

					Log.i("上次下载", lasttoalstr);
					starindex += lasttotal;
					total += lasttotal;
					fs.close();
				}

				conn.setRequestProperty("range", "bytes=" + starindex + "-"
						+ endindex);// 这里是设置 要请求文件的位置 连个参数
				// 如"range","bytes=1214-125456"
				int code = conn.getResponseCode();// 得到状态码 因为是下载服务器部分文件
				// 所以这个状态码 是206
				System.out.println("code:" + code);
				InputStream is = conn.getInputStream();// 得到输出流
				File file =new File(Environment.getExternalStorageDirectory(),getfilename(path));
				RandomAccessFile ra = new RandomAccessFile(file, "rw");
				ra.seek(starindex);// 开始写文件的地址

				int len = 0;

				byte[] buffer = new byte[1024];
				while ((len = is.read(buffer)) != -1) {
					ra.write(buffer, 0, len);// 循环写入到ra所指的的文件里
					total += len;// 断点续传加的代码 把已经写入的本地硬盘的文件保存起来
					// FileOutputStream fos = new FileOutputStream(fileinfo);//
					// 断点续传加的代码 这里是先写入到缓存区里 不可用
					RandomAccessFile rf = new RandomAccessFile(fileinfo, "rwd");// 这里是立即写入到本地硬盘,而不是先存放到缓冲区里
					rf.write(String.valueOf(total).getBytes());// 断点续传加的代码把已经下载好的文件保存到对应的txt里
					rf.close();
					pds.get(threadid-1).setProgress(total);
				}
				is.close();
				ra.close();

			} catch (Exception e) {
				e.printStackTrace();
				Message msg=Message.obtain();
				msg.what=THREADE_ERROR;
				handler.sendMessage(msg);
			} finally {
				// 定义同步 锁
				synchronized (MainActivity.class) {
					Log.i("线程:" + threadid, "下载完毕");
					threaddowncount--;
					if (threaddowncount < 1) {

						Log.i("线程:" + threadid, "下载完毕删除文件");
						for (int i = 1; i <= threadcount; i++) {
							File fi = new File(Environment.getExternalStorageDirectory(),i + ".txt");
							System.out.println(fi.delete());
							Message msg=Message.obtain();
							msg.what=DOWNLOAD_FINISH;
							handler.sendMessage(msg);
						}

					}
				}

			}
		}
	}

	private String  getfilename( String path)
	{
		int fileindex=path.lastIndexOf("/")+1;
		return path.substring(fileindex);
	}



权限

   <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=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入要下载的文件地址" />

    <EditText
        android:id="@+id/fileurl"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:text="http://192.168.0.101:8080/duoxianchengxiazai/Android.rar" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入要开启的线程" />

    <EditText
        android:id="@+id/count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:text="3" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="download"
        android:text="下载" />

    <LinearLayout
        android:id="@+id/ll_containt"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </LinearLayout>

</LinearLayout>

进度条布局

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/progressBar1"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值