android 客户端多线程下载

/**** 在配置文件中加入如下权限 A:访问网络的权限 B.C:能够对SD操做的权限 ***/ <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"/>java

/**主类?/ package com.example.downloadandprogressor;android

import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast;网络

public class MainActivity extends Activity {多线程

/***
 * 这个Activity操做是把网络资源下载到
 * 本地的SD卡中去
 * 咱们采用的是多线程技术进行操做下载
 * 因为手机的硬件资源有限--最好是开启的线程5条如下为好
 * 本操做也有进度条进行显示
 * 这里要注意的问题是:耗时的操做必须在子线程中操做--其实
 * 这里的操做最好由Service后台操做才好
 * 问题2:更新UI组件必需要在主线程中进行
 * 不然是不会有效果的
 * 
 */

private Handler myhandler =null;

private EditText url=null;
private Button down = null;
private Button exit=null;
private TextView sm=null;
private ProgressBar progrressbar=null;

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	//获取各个组件
	url=(EditText)findViewById(R.id.urlE);
	down=(Button)findViewById(R.id.down);
	exit=(Button)findViewById(R.id.tcxz);//退出按钮
	sm=(TextView)findViewById(R.id.jd);
	progrressbar=(ProgressBar)findViewById(R.id.progressbar);
	myhandler = new MyHander();//这里负责子线程和主线程的交互--更新UI
	down.setOnClickListener(new View.OnClickListener() {
		
		
		public void onClick(View v) {
			String path=url.getText().toString();
			startLoad(path,3);
			
		}

		
	});
	
	exit.setOnClickListener(new View.OnClickListener() {
		
		
		public void onClick(View v) {
			
			System.exit(0);
			
		}
	});
	
}

protected void startLoad(String path, int i) {
	
	try {
		DownLoadService.load(path,i,this.progrressbar,this.myhandler);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	// Inflate the menu; this adds items to the action bar if it is present.
	getMenuInflater().inflate(R.menu.activity_main, menu);
	return true;
}

private final class MyHander extends Handler{

	/***
	 * 因为更新UI要在主线程进行
	 * 又由于在子线程要有数据要返回给主线程
	 * 因此就要进行Handler操做
	 * 才能提供一个主线程和子线程交互的平台
	 * 
	 */
	
	public void handleMessage(Message msg) {
		// TODO Auto-generated method stub
		super.handleMessage(msg);
		
		if(msg.what==1){
			
			
			
		int size=msg.getData().getInt("size");
		progrressbar.setProgress(size);//设置当前的值
		
		if(progrressbar.getProgress()== progrressbar.getMax()){
			
			Toast.makeText(getApplicationContext(), "下载完成", Toast.LENGTH_LONG).show();
			sm.setText("100%");
		}else{
			
			float v = (float)progrressbar.getProgress() / (float)progrressbar.getMax();
			int k = (int)(v*100);
			sm.setText(k+"%");
		}
		
			
		}
		
	}
	
}

} /*负责下载的类service?/ package com.example.downloadandprogressor;app

import java.io.File; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL;dom

import android.os.Environment; import android.os.Handler; import android.widget.ProgressBar;ide

public class DownLoadService {this

public static void load(String path, int i,ProgressBar progrressbar,Handler myhandler) throws Exception{
	
	URL url = new URL(path);
	HttpURLConnection con = (HttpURLConnection)url.openConnection();
	con.setReadTimeout(5000);
	con.setRequestMethod("GET");
	//获取网络资源的长度
	int len = con.getContentLength();
	//获取SD卡路径
	String sdpath=DownLoadService.getSDpath();
	if(sdpath==null){
		System.out.println("-------------没有SD卡-------------------");
		return;
	}
	//建立一个本地的文件--并和其网络的资源大小同样
	File file = new File(sdpath,DownLoadService.getContentName(path));
	RandomAccessFile af = new RandomAccessFile(file, "rwd");
	//设置其文件的大小
	af.setLength(len);
	//计算每一个线程要下载的区域
	int block = (len%i) == 0 ? len/i : len/i+1;
	//为进度条设置最大的值
	progrressbar.setMax(len);

	
	//开始开启子线程进行下载
	for(int j=0;j<i;j++){
		
		new DownLoadThread(j,file,url,block,myhandler).start();
	}
	
	
}

private static String getContentName(String path) {
	
	return path.substring(path.lastIndexOf("/")+1);
}

private static String getSDpath() {
	String SDpath=null;
	if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
		SDpath=Environment.getExternalStorageDirectory().getPath();
	}
	return SDpath;
}

} /**负责下载的线程类?*/ package com.example.downloadandprogressor;url

import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL;.net

import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.Toast;

public class DownLoadThread extends Thread {

public static int size=0;

private int j;//线程的ID
private File file;//本地文件
private URL url;//网络资源路径
private int block;//下载的块
private Handler myhandler;//负责和线程进行交互


public DownLoadThread(int j, File file, URL url, int block,Handler myhandler) {
	
	this.j=j;
	this.file=file;
	this.url=url;
	this.block=block;
	this.myhandler=myhandler;
	
}

public void run() {
	
	try{
		HttpURLConnection con = (HttpURLConnection)url.openConnection();
		con.setReadTimeout(5000);
		con.setRequestMethod("GET");
		//计算开始点和结束点
		int start = (j*block);
		int end = (j+1)*block-1;
		
		RandomAccessFile af = new RandomAccessFile(file,"rwd");
		af.seek(start);//寻找写入的位置
		//设置请求的头文件--因为是多线程下载--因此要设置区域下载大小的头文件bytes=1-11
		con.setRequestProperty("Range", "bytes="+start+"-"+end);
		//根据返回的状态嘛判断是否成功
		if(con.getResponseCode() == 206 ){//下载连接成功的状态吗为 206
			InputStream in = con.getInputStream();
			byte[] buf = new byte[1024];
			int len=0;
			while((len=in.read(buf))!=-1){
				//计算目前总的下载量
				DownLoadThread.getSize(len,this.myhandler);
				af.write(buf,0,len);
			}
			af.close();
			in.close();
			System.out.println("第"+j+"线程完成下载");
		}else{
			System.out.println("第"+j+"线程没法完成下载");
		}
		
	}catch(Exception e){
		e.printStackTrace();
	}
	
	
}

private synchronized  static void getSize(int len,Handler myhandler) {
	
	DownLoadThread.size+=len;
	Message msg = new Message();
	Bundle b = new Bundle();
	b.putInt("size", DownLoadThread.size);
	msg.setData(b);
	msg.what=1;
	myhandler.sendMessage(msg);
	
}

}

相关文章
相关标签/搜索