Android中多線程下載

來源:互聯網
上載者:User
public class MainActivity extends Activity {// 聲明控制項// 路徑與線程數量private EditText et_url, et_num;// 進度條public static ProgressBar pb_thread;// 顯示進度的操作private TextView tv_pb;// 線程的數量public static int threadNum = 3;// 每個線程負責下載的大小public int blockSize;public static int threadCount;// 數量// 訪問的pathpublic String path;public static boolean flag = true;// 記錄進度條的值public static int pb_count = 0;public static Handler handler;public static final int TEXTVALUE = 1;public static int pb_num = 0;public static int size = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et_url = (EditText) findViewById(R.id.et_path);et_num = (EditText) findViewById(R.id.et_threadNum);pb_thread = (ProgressBar) findViewById(R.id.pb_down);tv_pb = (TextView) findViewById(R.id.tv_pb);handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case TEXTVALUE:System.out.println("-----------------------"+ MainActivity.pb_count + "//////"+ MainActivity.size);// 改變TEXTViewpb_num = (MainActivity.pb_count * 100) / MainActivity.size;tv_pb.setText("當前進度是+" + pb_num + "%");break;default:break;}}};}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.//getMenuInflater().inflate(R.menu.down, menu);return true;}//下載操作public void downLoad(View v) {// 改變變數值:MainActivity.flag = true;MainActivity.pb_count = 0;path = et_url.getText().toString();String threadNum_et = et_num.getText().toString();if (TextUtils.isEmpty(path) || TextUtils.isEmpty(threadNum_et)) {Toast.makeText(this, "不可為空", Toast.LENGTH_LONG).show();return;}Toast.makeText(this, "url:" + path + "--" + threadNum_et,Toast.LENGTH_LONG).show();// 轉換成數字threadNum = Integer.valueOf(threadNum_et);new Thread(new Runnable() {@Overridepublic void run() {try {// 建立出URL對象URL url = new URL(path);// 建立出 HttpURLConnection對象HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();// 設定 發請求發送的方式httpURLConnection.setRequestMethod("GET");// 佈建要求是否逾時時間httpURLConnection.setConnectTimeout(5000);// 設定httpURLConnection.setRequestProperty("User-Agent"," Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");// 是否響應成功if (httpURLConnection.getResponseCode() == 200) {// 擷取檔案的大小size = httpURLConnection.getContentLength();System.out.println("檔案的大小" + size);// 設定進度條的最大值pb_thread.setMax(size);// 建立檔案 //儲存到SD卡上// 首先判斷是否擁有sdcardif (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 擷取sdCard檔案目錄對象File sdFile = Environment.getExternalStorageDirectory();// 建立檔案對象File file = new File(sdFile, "youdao.exe");RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");// 設定檔案的大小accessFile.setLength(size);// 每個線程下載的大小blockSize = size / threadNum;// 開三個線程 操作此檔案for (int i = 1; i <= threadNum; i++) {// 1 2 3// 計算出每個線程開始的位置int startSize = (i - 1) * blockSize;// 結束位置int endSize = (i) * blockSize;// 當線程是最後一個線程的時候if (i == threadNum) {// 判斷檔案的大小是否大於計算出來的結束位置if (size > endSize) {// 結束位置 等於 檔案的大小endSize = size;}}// 為每個線程建立一個隨機的讀取RandomAccessFile threadAccessFile = new RandomAccessFile(file, "rwd");new Thread(new DownLoadThread(i,threadAccessFile, startSize, endSize,path)).start();}}}} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}//暫停操作public void downPause(View v) {Toast.makeText(this, "暫停", Toast.LENGTH_LONG).show();this.flag = false;}}

public class DownLoadThread implements Runnable {// 下載檔案的封裝public RandomAccessFile accessFile; // 線程下載檔案的起始位置public int startSize;public int endSize;// 檔案下載的path路徑public String path;public int threadId; // 線程的標識public DownLoadThread(int threadId, RandomAccessFile accessFile,int startSize, int endSize, String path) {this.threadId = threadId;this.accessFile = accessFile;this.startSize = startSize;this.endSize = endSize;this.path = path;}@Overridepublic void run() {// 執行run方法try {// 建立檔案到SD卡上去// 首先判斷是否擁有sdcardif (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 擷取sdCard檔案目錄對象File sdFile = Environment.getExternalStorageDirectory();File threadFile = new File(sdFile, threadId + ".txt");if (threadFile.exists()) {// 讀取該檔案的內容// 建立檔案的輸入資料流對象FileInputStream fis = new FileInputStream(threadFile);// 採用工具類讀取byte data[] = StreamTools.isToData(fis);// 轉化成字串String threadLen = new String(data);if ((threadLen != null) && (!"".equals(threadLen))) {startSize = Integer.valueOf(threadLen);// 解決 416bug的錯誤if (startSize > endSize) {startSize = endSize - 1;}}}// 建立檔案// 建立URL對象URL url = new URL(path);// 建立HttpURLConnection對象HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();// 佈建要求的頭httpURLConnection.setRequestMethod("GET");// 佈建要求是否逾時時間httpURLConnection.setConnectTimeout(5000);// 設定httpURLConnection.setRequestProperty("User-Agent"," Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");// 關鍵的設定httpURLConnection.setRequestProperty("Range", "bytes="+ startSize + "-" + endSize);// 輸出當前線程System.out.println("當前線程" + threadId + " 下載開始位置:" + startSize+ " 下載結束位置:" + endSize);// 響應成功// 設定隨機讀取檔案的 開始位置accessFile.seek(startSize);// 擷取相應流對象InputStream is = httpURLConnection.getInputStream();// 建立輸出資料流對象byte buffer[] = new byte[1024];int len = 0;int threadTotal = 0;// 每個線程下載後儲存記錄 /while ((len = is.read(buffer)) != -1) {accessFile.write(buffer, 0, len);threadTotal += len;// 記錄你寫入的長度 //xml檔案//改變進度條:setProgressBar(len);// 通過檔案記錄檔案下載的長度FileOutputStream fos = new FileOutputStream(threadFile);fos.write((threadTotal + "").getBytes());fos.flush();fos.close();//發送handler訊息MainActivity.handler.sendEmptyMessage(MainActivity.TEXTVALUE);if(!MainActivity.flag){return;}}accessFile.close();is.close();System.out.println(threadId + "線程執行完畢");// 線程操作synchronized (MainActivity.class) {MainActivity.threadCount++;if (MainActivity.threadCount >= MainActivity.threadNum) {for (int i = 1; i <= MainActivity.threadNum; i++) {// 擷取sdCard上的檔案File deleteFile = new File(sdFile, i + ".txt");if (deleteFile.exists()) {// 檔案刪除deleteFile.delete();}}}}}} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public synchronized void setProgressBar(int len){MainActivity.pb_count+=len;MainActivity.pb_thread.setProgress(MainActivity.pb_count);}}

public class StreamTools {public static byte[] isToData(InputStream is) throws IOException{// 位元組輸出資料流ByteArrayOutputStream bops = new ByteArrayOutputStream();// 讀取資料的緩衝區byte buffer[] = new byte[1024];// 讀取長度的記錄int len = 0;// 迴圈讀取while ((len = is.read(buffer)) != -1) {bops.write(buffer, 0, len);}// 把讀取的內容轉換成byte數組byte data[] = bops.toByteArray();bops.flush();bops.close();is.close();return data;}}

完整源碼請訪問:http://download.csdn.net/detail/chrp99/5616629

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.