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

来源:互联网 发布:数据库表设计例子 编辑:程序博客网 时间:2024/05/16 09:37

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


多线程下载思路

MainActivity

开启线程下载

使用handler更新界面进度

RandomAccessFile 可以指定读取位置

ProgressBarListener //接口回调

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

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

DownloadManager //下载管理类

download() //下载方法

DownloadThread //下载线程

1.png

代码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);       }}


2.png

/**

下载线程

*@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();              }       }}

0 0