Android从零开始(17)(多线程下载-上)(新)

多线程下载思路

MainActivity

开启线程下载

使用handler更新界面进度

RandomAccessFile 可以指定读取位置

ProgressBarListener //接口回调

setMax(int length) //设置进度条的最大刻度

setDownloadLength(int length) //每条线程每次下载的数据

DownloadManager //下载管理类

download() //下载方法

DownloadThread //下载线程

代码MainAcivity

[java] view plain copy print ?
  1. public class MainActivity extends Activityimplements OnClickListener {  
  2.        privateEditText et;  
  3.        privateTextView tv;  
  4.        privateProgressBar pb;  
  5.        privateButton bt;  
  6.        privatefinal static int SETMAX = 0;  
  7.        privatefinal static int SETLENGTH = 1;  
  8.        privateProgressBarListener pbl = new ProgressBarListener() {  
  9.   
  10.               @Override  
  11.               public void setMax(int max) {  
  12.                       Message msg = new Message();  
  13.                       msg.what = SETMAX;  
  14.                       msg.obj = max;  
  15.                       mHandler.sendMessage(msg);  
  16.   
  17.               }  
  18.   
  19.               @Override  
  20.               public void setLength(int length) {  
  21.                       Message msg = new Message();  
  22.                       msg.what = SETLENGTH;  
  23.                       msg.obj = length;  
  24.                       mHandler.sendMessage(msg);  
  25.   
  26.               }  
  27.        };  
  28.        privateHandler mHandler = new Handler(){  
  29.               public void handleMessage(Message msg) {  
  30.                      switch(msg.what) {  
  31.                      caseSETMAX:  
  32.                             pb.setMax((Integer) msg.obj);  
  33.                             break;  
  34.                      caseSETLENGTH:  
  35.                             pb.incrementProgressBy((Integer)msg.obj);  
  36.                             intnow = pb.getProgress() + (Integer)msg.obj ;  
  37.                             tv.setText((int)(((float)now/(float)pb.getMax())*100)+ "%");  
  38.                             break;  
  39.   
  40.                      }  
  41.               };  
  42.        };  
  43.        /**Called when the activity is first created. */  
  44.        @Override  
  45.        publicvoid onCreate(Bundle savedInstanceState) {  
  46.               super.onCreate(savedInstanceState);  
  47.               setContentView(R.layout.main);  
  48.               bt = (Button) findViewById(R.id.bt);  
  49.               pb = (ProgressBar) findViewById(R.id.pb);  
  50.               et = (EditText) findViewById(R.id.et);  
  51.               tv = (TextView) findViewById(R.id.tv);  
  52.               bt.setOnClickListener(this);  
  53.        }  
  54.   
  55.   
  56.        @Override  
  57.        publicvoid onClick(View v) {  
  58.               // 判断sdCard是否存在  
  59.               if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))  
  60.               {  
  61.                      Toast.makeText(this,"sdCrad不存在",300).show();  
  62.               }else{  
  63.   
  64.                      try{  
  65.                             DownloadManager.download(et.getText().toString(),Environment.getExternalStorageDirectory(),pbl);  
  66.                      }catch (Exception e) {  
  67.                             // TODO Auto-generated catch block  
  68.                             e.printStackTrace();  
  69.                      }  
  70.               }  
  71.        }  
  72.   
  73.   
  74. }  

DownloadManager

[java] view plain copy print ?
  1. public class DownloadManager {  
  2.   
  3.        privatefinal static int threadsize = 3;  
  4.        privateProgressBarListener listener;  
  5.   
  6.        publicDownloadManager(ProgressBarListener listener) {  
  7.               // TODO Auto-generated constructor stub  
  8.               this.listener = listener;  
  9.        }  
  10.   
  11.        publicboolean download(String path,File dir) throws Exception{  
  12.               URL url = new URL(path);  
  13.               HttpURLConnection conn =(HttpURLConnection) url.openConnection();  
  14.               conn.setRequestMethod("GET");  
  15.               conn.setConnectTimeout(5000);  
  16.               if(conn.getResponseCode() == 200){  
  17.                      //获取文件的大小  
  18.                      int filesize = conn.getContentLength();  
  19.                      //在本地生成一个和服务器上大小一样的文件  
  20.                      File file = new File(dir,getFileName(path));  
  21.                      RandomAccessFile raf = newRandomAccessFile(file, "rwd");  
  22.                      //指定文件的大小  
  23.                      raf.setLength(filesize);  
  24.                      raf.close();  
  25.                      //回调监听 让ProgressBar设置最大值?????  
  26.                      listener.setMax(filesize);  
  27.   
  28.   
  29.                      //计算每条线程的下载量  
  30.                      int block =filesize%threadsize==0?(filesize/threadsize)filesize/threadsize + 1);  
  31.   
  32.                      //开启线程去下载  
  33.                      for(intthreadid = 0;threadid< threadsize;threadid++){  
  34.                             new DownloadThread(threadid, path, dir,block, listener).start();  
  35.                      }  
  36.               }else{  
  37.                      returnfalse;  
  38.               }  
  39.               return true;  
  40.        }  
  41.   
  42.   
  43.        //得到文件的名称  
  44.        publicstatic String getFileName(String path){  
  45.               returnpath.substring(path.lastIndexOf("/")+1);  
  46.        }  
  47. }  


/**

下载线程

*@author ThinkPad

*

*/

DownloadThread

[java] view plain copy print ?
  1. public class DownloadThread extends Thread {  
  2.   
  3.        //下载线程的id  
  4.        privateint threadid;  
  5.   
  6.        //下载路径  
  7.        privateString path;  
  8.   
  9.        //文件存储的目录  
  10.        privateFile dir ;  
  11.   
  12.        //每条线程的下载量  
  13.        privateint block;  
  14.   
  15.        //文件下载的开始位置  
  16.        privateint startPosition;  
  17.        //文件下载的结束位置  
  18.        privateint endPosition;  
  19.   
  20.        //下载的监听  
  21.        privateProgressBarListener listener;  
  22.   
  23.        publicDownloadThread(int threadid, String path, File dir,  
  24.                      intblock, ProgressBarListener listener) {  
  25.               super();  
  26.               this.threadid = threadid;  
  27.               this.path = path;  
  28.               this.dir = dir;  
  29.               this.block = block;  
  30.               this.listener = listener;  
  31.   
  32.               //计算出开始位置和结束位置  
  33.               this.startPosition= threadid*block;  
  34.               this.endPosition =(threadid+1)*block - 1;  
  35.        }  
  36.   
  37.   
  38.        @Override  
  39.        publicvoid run() {  
  40.               // TODO Auto-generated method stub  
  41.               super.run();  
  42.               try {  
  43.   
  44.                      //先准备一个RandomAccessFile  
  45.                      Filefile = new File(dir,DownloadManager.getFileName(path));  
  46.                      RandomAccessFile raf = newRandomAccessFile(file, "rwd");  
  47.                      //把指针指向你要写入的位置  
  48.                      raf.seek(startPosition);  
  49.                        
  50.                      //联网去获取网络上的数据  
  51.                      URLurl = new URL(path);  
  52.                      HttpURLConnectionconn = (HttpURLConnection) url.openConnection();  
  53.                      conn.setRequestMethod("GET");  
  54.                      conn.setConnectTimeout(5000);  
  55.                      //你需要指定网络上的资源也有开始位置和结束位置  
  56.                      conn.setRequestProperty("Range","bytes="+startPosition+"-"+endPosition);  
  57.                      //***不去判断是否是200***  
  58.                      InputStreamis = conn.getInputStream();  
  59.                      byte[]buffer = new byte[1024];  
  60.                      intlen = 0;  
  61.                      while((len= is.read(buffer)) != -1){  
  62.                             //把数据写入到文件  
  63.                             raf.write(buffer, 0, len);  
  64.                             //对进度条进行更新  
  65.                             listener.setLength(len);  
  66.                      }  
  67.                      is.close();  
  68.                      raf.close();  
  69.   
  70.               } catch (Exception e) {  
  71.                      //TODO Auto-generated catch block  
  72.                      e.printStackTrace();  
  73.               }  
  74.   
  75.        }  
  76.   

你可能感兴趣的:(Android从零开始(17)(多线程下载-上)(新))