Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中多線程下載

Android中多線程下載

編輯:關於Android編程

[java]
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;// 數量  
 
    // 訪問的path  
    public 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; 
 
    @Override 
    protected 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() { 
            @Override 
            public void handleMessage(Message msg) { 
                super.handleMessage(msg); 
                switch (msg.what) { 
                case TEXTVALUE: 
                    System.out.println("-----------------------" 
                            + MainActivity.pb_count + "//////" 
                            + MainActivity.size); 
                 
                    // 改變TEXTView  
                    pb_num = (MainActivity.pb_count * 100) / MainActivity.size; 
                    tv_pb.setText("當前進度是+" + pb_num + "%"); 
                    break; 
 
                default: 
                    break; 
                } 
            } 
        }; 
 
    } 
 
    @Override 
    public 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() { 
 
            @Override 
            public 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卡上  
 
                        // 首先判斷是否擁有sdcard  
                        if (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 block  
                    e.printStackTrace(); 
                } catch (IOException e) { 
                    // TODO Auto-generated catch block  
                    e.printStackTrace(); 
                } 
 
            } 
        }).start(); 
 
    } 
 
    //暫停操作  
    public void downPause(View v) { 
        Toast.makeText(this, "暫停", Toast.LENGTH_LONG).show(); 
 
        this.flag = false; 
 
    } 

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;// 數量

 // 訪問的path
 public 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;

 @Override
 protected 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() {
   @Override
   public void handleMessage(Message msg) {
    super.handleMessage(msg);
    switch (msg.what) {
    case TEXTVALUE:
     System.out.println("-----------------------"
       + MainActivity.pb_count + "//////"
       + MainActivity.size);
    
     // 改變TEXTView
     pb_num = (MainActivity.pb_count * 100) / MainActivity.size;
     tv_pb.setText("當前進度是+" + pb_num + "%");
     break;

    default:
     break;
    }
   }
  };

 }

 @Override
 public 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() {

   @Override
   public 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卡上

      // 首先判斷是否擁有sdcard
      if (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 block
     e.printStackTrace();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }

   }
  }).start();

 }

 //暫停操作
 public void downPause(View v) {
  Toast.makeText(this, "暫停", Toast.LENGTH_LONG).show();

  this.flag = false;

 }
}

 

 


[java]
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; 
    } 
 
    @Override 
    public void run() { 
        // 執行run方法  
        try { 
 
            // 創建文件到SD卡上去  
 
            // 首先判斷是否擁有sdcard  
            if (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 block  
            e.printStackTrace(); 
        } catch (IOException e) { 
            // TODO Auto-generated catch block  
            e.printStackTrace(); 
        } 
 
    } 
 
     
     
     
    public synchronized void setProgressBar(int len){ 
        MainActivity.pb_count+=len; 
        MainActivity.pb_thread.setProgress(MainActivity.pb_count); 
    } 
     
     
     

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;
 }

 @Override
 public void run() {
  // 執行run方法
  try {

   // 創建文件到SD卡上去

   // 首先判斷是否擁有sdcard
   if (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 block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

 
 
 
 public synchronized void setProgressBar(int len){
  MainActivity.pb_count+=len;
  MainActivity.pb_thread.setProgress(MainActivity.pb_count);
 }
 
 
 
}
[java] view plaincopyprint?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; 
    } 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved