<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/et" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="http://192.168.0.105/test.avi" android:hint="輸入文件地址" /> <ProgressBar android:id="@+id/pb" android:layout_width="fill_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" /> <TextView android:id="@+id/tv_proccess" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="當前進度" /> <Button android:id="@+id/et" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下載" android:onClick="click" /> </LinearLayout>
activity文件 java
package com.muliteThread.down; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { protected static final int DOWN_FAIL = 1; protected static final int DOWN_SUCCESS = 2; protected static final int DOWN_FINISH = 3; protected static final int UPDATE_TV_PROCCESS = 4; private EditText et; private int threadCount = 3; //須要幾個線程; private int runThread = 3; private ProgressBar pb; private TextView tv_proccess; private int currentProcess = 0; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { switch(msg.what){ case DOWN_SUCCESS: Toast.makeText(MainActivity.this, "下載成功", Toast.LENGTH_SHORT).show(); break; case DOWN_FAIL: Toast.makeText(MainActivity.this, "下載失敗", Toast.LENGTH_SHORT).show(); break; case DOWN_FINISH: Toast.makeText(MainActivity.this, "下載完成", Toast.LENGTH_SHORT).show(); break; case UPDATE_TV_PROCCESS: int b1 = (pb.getProgress())/1000; //這超過整型範圍不知道java裏面怎麼處理 int b2 = (pb.getMax())/100000; tv_proccess.setText("當前進度:"+b1/b2); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et = (EditText) findViewById(R.id.et); pb = (ProgressBar) findViewById(R.id.pb); tv_proccess = (TextView) findViewById(R.id.tv_proccess); } public void click(View view) { final String path = et.getText().toString().trim(); if (TextUtils.isEmpty(path)) { Toast.makeText(this, "路徑不能爲空", Toast.LENGTH_SHORT).show(); } new Thread(){ public void run(){ try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); int code = conn.getResponseCode(); if (code == 200) { int lens = conn.getContentLength(); int blockSize = lens / threadCount; pb.setMax(lens); RandomAccessFile raf = new RandomAccessFile(MainActivity.this.getFilesDir()+"test.avi", "rw"); raf.setLength(lens); for (int i = 1; i <= threadCount; i++) { int startIndex = (i-1)*blockSize; int endIndex = i*blockSize - 1; if (i == threadCount) { endIndex = lens; } new downloadThread(path,i,startIndex,endIndex).start(); System.out.println("線程:"+i+",開始位置:"+startIndex+",結束位置:"+endIndex); } } } catch (Exception e) { e.printStackTrace(); Message msg = new Message(); msg.what = DOWN_FAIL; handler.sendMessage(msg); } } }.start(); } class downloadThread extends Thread { private String path; private int threadId; private int startIndex; private int endIndex; public downloadThread(String path,int threadId,int start,int end) { this.path = path; this.threadId = threadId; this.startIndex = start; this.endIndex = end; } public void run() { try { File file = new File(MainActivity.this.getFilesDir()+"/"+threadId+".txt"); if (file.exists() && file.length() > 1) { FileInputStream fis = new FileInputStream(file); byte[] temp = new byte[1024]; int len = fis.read(temp); String downLen = new String(temp, 0, len); int downInt = Integer.parseInt(downLen); int alreadyDown = downInt - startIndex; System.out.println("xxxa"+alreadyDown+""); currentProcess+=alreadyDown; startIndex = downInt; fis.close(); } System.out.println("線程:"+threadId+",開始:"+startIndex); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); conn.setRequestMethod("GET"); conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); int code = conn.getResponseCode(); System.out.println(code); InputStream is = conn.getInputStream(); RandomAccessFile raf = new RandomAccessFile(MainActivity.this.getFilesDir()+"/test.avi", "rw"); raf.seek(startIndex); byte[] buffer = new byte[1024]; int len = 0; int total = 0; while ((len = is.read(buffer)) != -1) { RandomAccessFile tmp = new RandomAccessFile(MainActivity.this.getFilesDir()+"/"+threadId+".txt", "rw"); raf.write(buffer, 0, len); total+=len; tmp.write(((startIndex+total)+"").getBytes()); tmp.close(); //更新進度條 synchronized (MainActivity.this) { currentProcess+=len; pb.setProgress(currentProcess); Message msg = new Message(); msg.what = UPDATE_TV_PROCCESS; handler.sendMessage(msg); } } System.out.println("線程:"+threadId+"下載完畢"); } catch (Exception e) { e.printStackTrace(); } finally { downFinish(); //線程可能執行到runThread--的時候線程時間就到了;因此必須加鎖 } } private synchronized void downFinish() { runThread--; if (runThread == 0) { //全部線程執行完畢; for(int i = 1 ;i<=3; i++){ File file = new File(i+".txt"); System.out.println(file.length()); boolean res = file.delete(); System.out.println(res); } Message msg = new Message(); msg.what = DOWN_FINISH; handler.sendMessage(msg); } } } }
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>