多线程下载-上(断点)

多线程下载思路

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();

              }


       }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值