安卓多線程下載 學習筆記

佈局文件
<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"/>
相關文章
相關標籤/搜索