多线程断点下载文件

MainActivity.java


public class MainActivity extends Activity implements android.view.View.OnClickListener{

    private Button button;
    private ProgressBar progressBar;
    private TextView textView;
    private Handler handler;
    boolean stopflag = false;
    private static String path = "http://192.168.1.100:8080/YoudaoDict_6.3.69.3028_setup.1459323013.exe";
    static long len = 0;
    int total = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); 
        button = (Button) findViewById(R.id.button1);
        progressBar = (ProgressBar) findViewById(R.id.progressBar1); 
        textView = (TextView) findViewById(R.id.id_tv_loadingmsg);
        button.setOnClickListener(this); 


        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                if(0x110 == msg.what){
                    Log.d("handleMessage", "msg.obj:"+msg.obj.toString());
                    int value = Integer.parseInt(msg.obj.toString());
                    value = (int)((double)value / len * 100);
                    progressBar.setProgress(value) ; 
                    textView.setText("已经下载"+value+"%...");
                    if(value>=100){
                        System.out.println("安装完成========");
                        stopflag = true;
                        button.setText("安装");
                    }// cp /data/data/com.thunder.main/files/YoudaoDict_6.3.69.3028_setup.1459323013.exe /storage/external_storage/udisk0/
                }
            }
        }; 
    }



    @SuppressLint("NewApi")
    class MyTask extends AsyncTask<String, Integer, String>{

        Context context;
        int threadid;
        String filepath;
        long startposition;
        long endpositon;

        public MyTask(Context context){
            this.context = context; 
        }

        public MyTask(Context context,int i, String path, long startposition, long endpositon) {
            this.context = context; 
            this.threadid = i;
            this.filepath =path;
            this.startposition = startposition;
            this.endpositon = endpositon;
        }

        @Override
        protected String doInBackground(String... params) {

            try {
                File postionfile = new File(getFilesDir()+"/" + threadid + ".txt");
                URL url = new URL(filepath);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection(); 
//
                if (postionfile.exists()) {
                    FileInputStream fis = new FileInputStream(postionfile);
                    byte[] result = Utils.getBytes(fis);
                    String str = new String(result);
                    if (!"".equals(str)) {
                        int newstartposition = Integer.parseInt(str);
                        if (newstartposition > startposition) {
                            startposition = newstartposition;
                        }
                    }
                    fis.close();
                }

                // "Range", "bytes=2097152-4194303")
                conn.setRequestProperty("Range", "bytes=" + startposition + "-"
                        + endpositon);
//              conn.setRequestMethod("GET");
//              conn.setConnectTimeout(5000);
//              conn.setRequestProperty("User-Agent",
//                      "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                InputStream is = conn.getInputStream();

                BufferedInputStream bufferedInputStream = new BufferedInputStream(is);

                RandomAccessFile file = new RandomAccessFile(getFilesDir()+"/"
                        + Utils.getFilenName(filepath), "rwd");
                file.seek(startposition);
                byte[] buffer = new byte[4096];
                int mlen = 0;
                long currentPostion = startposition;

                // 创建一个文件对象 ,记录当前某个文件的下载位置 
                while ((mlen = bufferedInputStream.read(buffer)) != -1) {
                    if (stopflag) {
                        return null;
                    }
                    file.write(buffer, 0, mlen);

                    synchronized (context.getClass()) {
                        total += mlen;
                    }
                    currentPostion += mlen;
                    // 需要把currentPostion 信息给持久化到存储设备
                    String position = currentPostion + "";
                    FileOutputStream fos = new FileOutputStream(postionfile);
                    fos.write(position.getBytes());
                    fos.flush();
                    fos.close();

                }

                file.close();
                bufferedInputStream.close();
                System.out.println("线程" + threadid + "下载完毕");
                // 当线程下载完毕后 把文件删除掉
                if (postionfile.exists()) {
                    postionfile.delete();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return threadid+" ok";
        }

        @Override
        protected void onPreExecute() {

        }

        @Override
        protected void onPostExecute(String result) {
            if(result!=null){
                Toast.makeText(context,result,1000).show();
                System.out.println(result);
            } 
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values); 
        } 
    }

    public void dowork(){
        String string = button.getText().toString();
        if("开始".equals(string)){
            button.setText("暂停"); 
            stopflag = false; 
        }else{
            button.setText("开始");
            stopflag = true; 
        }
        //定时更新进度 

        new Thread() {

            @Override
            public void run() {
                    while (!stopflag) {
                    try {
                        sleep(2000);
                        Message message = new Message();
                        message.what = 0x110; 
                        synchronized (getApplicationContext().getClass()) {
                            message.obj =  total;
                            handler.sendMessage(message);
                        }


                    } catch (InterruptedException e) {
                        //TODO 异常处理 
                        e.printStackTrace();
                    }

                }
            }
        }.start();


        try {
            RandomAccessFile file = new RandomAccessFile(
                    getFilesDir() +"/"+ Utils.getFilenName(path), "rwd");
            file.setLength(len);
        } catch (IOException e) {
                e.printStackTrace();
        }

        // 2 .假设开启3 个线程
        int threadnumber = 3;
        long blocksize = len / threadnumber;
        /**
         * 线程1 0~ blocksize 线程2 1*bolocksize ~ 2*blocksize 线程3
         * 2*blocksize ~ 文件末尾
         */
        for (int i = 0; i < threadnumber; i++) {
            long startposition = i * blocksize;
            long endpositon = (i + 1) * blocksize;
            if (i == (threadnumber - 1)) {
                    endpositon = len;
            } 

            Log.d("aaaa", i+"#:"+startposition+"-"+endpositon); 

            new MyTask(MainActivity.this,i, path,
                    startposition, endpositon).execute("");
        } 
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button1:
            //获取文件大小后开始下载
            final FileHandler imageHandler = new FileHandler(new AsyncLoaderListener() {
                @Override
                public void onImageLoader() {
                    dowork();
                }
            });
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try { 

                        URL url = new URL(path);
                        URLConnection openConnection = url.openConnection();
                        int contentLength = openConnection.getContentLength();
                        len = contentLength;
                        Message message = new Message();
                        message.what = 0x111;
                        message.obj = contentLength;
                        imageHandler.sendMessage(message);
                    } catch (IOException e) {
                        System.out.println("获取文件大小失败");
                        Toast.makeText(MainActivity.this, "网络连接异常,请确认服务是否打开", 1000).show();
                        e.printStackTrace();
                    }
                }
            }).start(); 

            break;

        default:
            break;
        }
    }

    /** 异步获取文件大小接口 */
    public interface AsyncLoaderListener {
        void onImageLoader();
    }

    /** 异步获取文件大小完成后,下载处理 */
    static class FileHandler extends Handler {

        private AsyncLoaderListener listener;

        public FileHandler(AsyncLoaderListener listener) {
            this.listener = listener;
        }

        @Override
        public void handleMessage(Message msg) {
            if(0x111 == msg.what){
                    len = Integer.parseInt(msg.obj.toString());
                    listener.onImageLoader();
             } 
        }
    }

}



Utils.java

public class Utils {
    /**
     * 把一个inputstream里面的内容转化成一个byte[] 
     */

    public static byte[] getBytes(InputStream is) throws Exception{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = is.read(buffer))!=-1){
            bos.write(buffer, 0, len);
        }
        is.close();
        bos.flush();
        byte[] result = bos.toByteArray();
        return  result;
    }


    public static String getFilenName(String path) {
        int start = path.lastIndexOf("/") + 1;
        return path.substring(start, path.length());
    }
}

注意:如果正在下载时,按返回键,然后再次启动的时候,将重新下载。

!!!!!!!!!
还可以使用XUtils 3.0框架做断点续传,http://blog.csdn.net/wuqingyidongren/article/details/51093394

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值