现在的位置: 首页 > 综合 > 正文

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

2017年02月12日 ⁄ 综合 ⁄ 共 4150字 ⁄ 字号 评论关闭

转载请注明本文出自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();
              }

       }

}

抱歉!评论已关闭.