android典型程式碼系列(二十)------多執行緒下載、斷點續傳

fandong12388發表於2015-12-04

20多執行緒下載 :

public class DemoActivity extends Activity implements OnClickListener {

    private ProgressBar pb;
    private Button bt;
    private TextView tv;
    private EditText et;
    boolean flag = true;
    boolean stopflag = false;
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            pb.setProgress(total);

            int max = pb.getMax();
            if (total >= (max - 1)) {
                total = max;
                flag = false;
            }
            int result = total * 100 / max;
            tv.setText("當前進度 :" + result + "%");

            super.handleMessage(msg);
        }
    };

    int total = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        pb = (ProgressBar) this.findViewById(R.id.pb);
        bt = (Button) this.findViewById(R.id.bt);
        tv = (TextView) this.findViewById(R.id.tv_process);
        et = (EditText) this.findViewById(R.id.et);
        bt.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bt:
            // 建立一個子執行緒 定期的更新ui
            if("開始下載".equals(bt.getText().toString())){
                bt.setText("暫停");
                stopflag = false; //開始下載 
            }
            else {
                bt.setText("開始下載");
                stopflag = true;
            }
            new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        while (flag) {
                            try {
                                sleep(1000);
                                // 如果total > = 檔案長度
                                Message msg = new Message();
                                handler.sendMessage(msg);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }.start();

                // 開始執行下載的操作
                String path = et.getText().toString().trim();
                if ("".equals(path)) {
                    Toast.makeText(this, "路徑不能為空", 1).show();
                    return;
                }
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url
                            .openConnection();
                    conn.setRequestMethod("GET");
                    conn.setConnectTimeout(5000);
                    conn.setRequestProperty("User-Agent",
                            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                    int code = conn.getResponseCode();
                    if (code == 200) {
                        int len = conn.getContentLength();
                        RandomAccessFile file = new RandomAccessFile(
                                "/mnt/sdcard/" + getFilenName(path), "rwd");
                        // 1.設定本地檔案大小跟伺服器的檔案大小一致
                        file.setLength(len);
                        // 設定進度條的最大值
                        pb.setMax(len);

                        // 2 .假設開啟3 個執行緒
                        int threadnumber = 3;
                        int blocksize = len / threadnumber;
                        /**
                         * 執行緒1 0~ blocksize 執行緒2 1*bolocksize ~ 2*blocksize 執行緒3
                         * 2*blocksize ~ 檔案末尾
                         */
                        for (int i = 0; i < threadnumber; i++) {
                            int startposition = i * blocksize;
                            int endpositon = (i + 1) * blocksize;
                            if (i == (threadnumber - 1)) {
                                // 最後一個執行緒
                                endpositon = len;
                            }

                            DownLoadTask task = new DownLoadTask(i, path,
                                    startposition, endpositon);
                            task.start();
                        }

                    }
                } catch (Exception e) {
                    Toast.makeText(this, "下載出現異常", 0).show();
                    e.printStackTrace();
                }

            break;
        }

    }

    class DownLoadTask extends Thread {

        int threadid;
        String filepath;
        int startposition;
        int endpositon;

        public DownLoadTask(int threadid, String filepath, int startposition,
                int endpositon) {
            this.threadid = threadid;
            this.filepath = filepath;
            this.startposition = startposition;
            this.endpositon = endpositon;

        }

        @Override
        public void run() {
            try {
                //將斷點檔案儲存到SD卡上面
                File postionfile = new File("/mnt/sdcard/" + threadid + ".txt");
                URL url = new URL(filepath);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                System.out.println("執行緒" + threadid + "正在下載 " + "開始位置 : "
                        + startposition + "結束位置 " + endpositon);

                if (postionfile.exists()) {
                    FileInputStream fis = new FileInputStream(postionfile);
                    byte[] result = StreamTool.getBytes(fis);
                    String str = new String(result);
                    if (!"".equals(str)) {
                        int newstartposition = Integer.parseInt(str);
                        if (newstartposition > startposition) {
                            startposition = newstartposition;
                        }
                    }
                }
                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();
                RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/"+ getFilenName(filepath), "rwd");
                file.seek(startposition);
                byte[] buffer = new byte[1024];
                int len = 0;
                int currentPostion = startposition;
                while ((len = is.read(buffer)) != -1) {
                    if (stopflag) {
                        return;
                    }
                    file.write(buffer, 0, len);
                    synchronized (DemoActivity.this) {
                        total += len;
                    }

                    currentPostion += len;
                    String position = currentPostion + "";
                    FileOutputStream fos = new FileOutputStream(postionfile);
                    fos.write(position.getBytes());
                    fos.flush();
                    fos.close();
                }

                file.close();
                System.out.println("執行緒" + threadid + "下載完畢");
                if (postionfile.exists()) {
                    postionfile.delete();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

            super.run();
        }

    }

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

相關文章