转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
多线程下载思路
MainActivity
开启线程下载
使用handler更新界面进度
RandomAccessFile 可以指定读取位置
ProgressBarListener //接口回调
setMax(int length) //设置进度条的最大刻度
setDownloadLength(int length) //每条线程每次下载的数据
DownloadManager //下载管理类
download() //下载方法
DownloadThread //下载线程
代码MainAcivity
public class MainActivity extends Activityimplements OnClickListener { privateEditText et; privateTextView tv; privateProgressBar pb; privateButton bt; privatefinal static int SETMAX = 0; privatefinal static int SETLENGTH = 1; privateProgressBarListener pbl = new ProgressBarListener() { @Override public void setMax(int max) { Message msg = new Message(); msg.what = SETMAX; msg.obj = max; mHandler.sendMessage(msg); } @Override public void setLength(int length) { Message msg = new Message(); msg.what = SETLENGTH; msg.obj = length; mHandler.sendMessage(msg); } }; privateHandler mHandler = new Handler(){ public void handleMessage(Message msg) { switch(msg.what) { caseSETMAX: pb.setMax((Integer) msg.obj); break; caseSETLENGTH: pb.incrementProgressBy((Integer)msg.obj); intnow = pb.getProgress() + (Integer)msg.obj ; tv.setText((int)(((float)now/(float)pb.getMax())*100)+ "%"); break; } }; }; /**Called when the activity is first created. */ @Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bt = (Button) findViewById(R.id.bt); pb = (ProgressBar) findViewById(R.id.pb); et = (EditText) findViewById(R.id.et); tv = (TextView) findViewById(R.id.tv); bt.setOnClickListener(this); } @Override publicvoid onClick(View v) { // 判断sdCard是否存在 if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(this,"sdCrad不存在",300).show(); }else{ try{ DownloadManager.download(et.getText().toString(),Environment.getExternalStorageDirectory(),pbl); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
DownloadManager
public class DownloadManager { privatefinal static int threadsize = 3; privateProgressBarListener listener; publicDownloadManager(ProgressBarListener listener) { // TODO Auto-generated constructor stub this.listener = listener; } publicboolean download(String path,File dir) throws Exception{ URL url = new URL(path); HttpURLConnection conn =(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if(conn.getResponseCode() == 200){ //获取文件的大小 int filesize = conn.getContentLength(); //在本地生成一个和服务器上大小一样的文件 File file = new File(dir,getFileName(path)); RandomAccessFile raf = newRandomAccessFile(file, "rwd"); //指定文件的大小 raf.setLength(filesize); raf.close(); //回调监听 让ProgressBar设置最大值????? listener.setMax(filesize); //计算每条线程的下载量 int block =filesize%threadsize==0?(filesize/threadsize)filesize/threadsize + 1); //开启线程去下载 for(intthreadid = 0;threadid< threadsize;threadid++){ new DownloadThread(threadid, path, dir,block, listener).start(); } }else{ returnfalse; } return true; } //得到文件的名称 publicstatic String getFileName(String path){ returnpath.substring(path.lastIndexOf("/")+1); } }
/**
* 下载线程
*@author ThinkPad
*
*/
DownloadThread
public class DownloadThread extends Thread { //下载线程的id privateint threadid; //下载路径 privateString path; //文件存储的目录 privateFile dir ; //每条线程的下载量 privateint block; //文件下载的开始位置 privateint startPosition; //文件下载的结束位置 privateint endPosition; //下载的监听 privateProgressBarListener listener; publicDownloadThread(int threadid, String path, File dir, intblock, ProgressBarListener listener) { super(); this.threadid = threadid; this.path = path; this.dir = dir; this.block = block; this.listener = listener; //计算出开始位置和结束位置 this.startPosition= threadid*block; this.endPosition =(threadid+1)*block - 1; } @Override publicvoid run() { // TODO Auto-generated method stub super.run(); try { //先准备一个RandomAccessFile Filefile = new File(dir,DownloadManager.getFileName(path)); RandomAccessFile raf = newRandomAccessFile(file, "rwd"); //把指针指向你要写入的位置 raf.seek(startPosition); //联网去获取网络上的数据 URLurl = new URL(path); HttpURLConnectionconn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); //你需要指定网络上的资源也有开始位置和结束位置 conn.setRequestProperty("Range","bytes="+startPosition+"-"+endPosition); //***不去判断是否是200*** InputStreamis = conn.getInputStream(); byte[]buffer = new byte[1024]; intlen = 0; while((len= is.read(buffer)) != -1){ //把数据写入到文件 raf.write(buffer, 0, len); //对进度条进行更新 listener.setLength(len); } is.close(); raf.close(); } catch (Exception e) { //TODO Auto-generated catch block e.printStackTrace(); } } }