当我们学完java中多线程的下载后,可以将它移植到我们的安卓中来,下面是具体实现源码:
DownActivity.java
-
package com.example.downloads;
-
-
import java.io.File;
-
import java.io.IOException;
-
import java.io.RandomAccessFile;
-
import java.net.HttpURLConnection;
-
import java.net.MalformedURLException;
-
import java.net.URL;
-
import com.example.downloads.utils.DownLoadThread;
-
import android.os.Bundle;
-
import android.os.Environment;
-
import android.os.Handler;
-
import android.os.Message;
-
import android.annotation.SuppressLint;
-
import android.app.Activity;
-
import android.text.TextUtils;
-
import android.view.Menu;
-
import android.view.View;
-
import android.widget.EditText;
-
import android.widget.ProgressBar;
-
import android.widget.TextView;
-
import android.widget.Toast;
-
-
public class DownActivity extends Activity {
-
-
-
public EditText et_url, et_num;
-
-
public static ProgressBar pb_thread;
-
-
public TextView tv_pb;
-
-
public static int threadNum = 3;
-
-
public int blockSize;
-
public static int threadCount;
-
-
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_down);
-
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() {
-
@SuppressLint("HandlerLeak")
-
@Override
-
public void handleMessage(Message msg) {
-
super.handleMessage(msg);
-
switch (msg.what) {
-
case TEXTVALUE:
-
System.out.println("-------" + DownActivity.pb_count
-
+ "//////" + DownActivity.size);
-
-
pb_num = (DownActivity.pb_count * 100) / DownActivity.size;
-
tv_pb.setText("当前进度是+" + pb_num + "%");
-
-
break;
-
-
default:
-
break;
-
}
-
}
-
-
};
-
-
}
-
-
@Override
-
public boolean onCreateOptionsMenu(Menu menu) {
-
-
getMenuInflater().inflate(R.menu.main, menu);
-
return true;
-
}
-
-
public void downLoad(View v) {
-
DownActivity.flag = true;
-
DownActivity.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 = new URL(path);
-
-
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);
-
-
-
-
-
if (Environment.getExternalStorageState().equals(
-
Environment.MEDIA_MOUNTED)) {
-
-
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++) {
-
-
-
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) {
-
-
e.printStackTrace();
-
} catch (IOException e) {
-
-
e.printStackTrace();
-
}
-
-
}
-
-
}).start();
-
}
-
-
-
-
-
-
-
public void downPause(View v) {
-
Toast.makeText(this, "暂停", Toast.LENGTH_LONG).show();
-
-
this.flag = false;
-
-
}
-
-
}
DownLoadThread.java
-
package com.example.downloads.utils;
-
-
import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.RandomAccessFile;
-
import java.net.HttpURLConnection;
-
import java.net.MalformedURLException;
-
import java.net.URL;
-
-
import com.example.downloads.DownActivity;
-
-
import android.os.Environment;
-
-
-
-
public class DownLoadThread implements Runnable {
-
-
-
public RandomAccessFile accessFile;
-
-
-
public int startSize;
-
public int endSize;
-
-
-
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() {
-
-
try {
-
-
-
-
-
if (Environment.getExternalStorageState().equals(
-
Environment.MEDIA_MOUNTED)) {
-
-
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);
-
-
-
if (startSize > endSize) {
-
startSize = endSize - 1;
-
}
-
}
-
-
}
-
-
-
-
-
URL url = new URL(path);
-
-
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;
-
-
-
setProgressBar(len);
-
-
FileOutputStream fos = new FileOutputStream(threadFile);
-
fos.write((threadTotal + "").getBytes());
-
fos.flush();
-
fos.close();
-
-
DownActivity.handler.sendEmptyMessage(DownActivity.TEXTVALUE);
-
if(!DownActivity.flag){
-
return;
-
}
-
-
}
-
accessFile.close();
-
is.close();
-
System.out.println(threadId + "线程执行完毕");
-
-
-
synchronized (DownActivity.class) {
-
DownActivity.threadCount++;
-
if (DownActivity.threadCount >= DownActivity.threadNum) {
-
for (int i = 1; i <= DownActivity.threadNum; i++) {
-
-
File deleteFile = new File(sdFile, i + ".txt");
-
if (deleteFile.exists()) {
-
-
deleteFile.delete();
-
}
-
}
-
}
-
}
-
}
-
} catch (MalformedURLException e) {
-
-
e.printStackTrace();
-
} catch (IOException e) {
-
-
e.printStackTrace();
-
}
-
-
}
-
-
-
-
-
public synchronized void setProgressBar(int len){
-
DownActivity.pb_count+=len;
-
DownActivity.pb_thread.setProgress(DownActivity.pb_count);
-
}
-
-
-
-
}
StreamTools.java
-
package com.example.downloads.utils;
-
-
import java.io.ByteArrayOutputStream;
-
import java.io.IOException;
-
import java.io.InputStream;
-
-
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 data[] = bops.toByteArray();
-
-
bops.flush();
-
bops.close();
-
is.close();
-
return data;
-
}
-
}
strings.xml
-
<?xml version="1.0" encoding="utf-8"?>
-
<resources>
-
-
<string name="app_name">downloads</string>
-
<string name="action_settings">Settings</string>
-
<string name="tv_down">文件下载的地址</string>
-
<string name="tv_threadNum">线程数量</string>
-
<string name="tv_num">0%</string>
-
<string name="btn_text">下载</string>
-
<string name="btn_pause">暂停</string>
-
<string name="et_path">http://172.22.64.8:8080/doudou/youdao.exe</string>
-
<string name="et_threadNum">3</string>
-
-
</resources>
布局文件:
-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
xmlns:tools="http://schemas.android.com/tools"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:paddingBottom="@dimen/activity_vertical_margin"
-
android:paddingLeft="@dimen/activity_horizontal_margin"
-
android:paddingRight="@dimen/activity_horizontal_margin"
-
android:paddingTop="@dimen/activity_vertical_margin"
-
tools:context=".DownActivity" >
-
-
<TextView
-
android:id="@+id/textView1"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignParentLeft="true"
-
android:layout_alignParentTop="true"
-
android:text="@string/tv_down" />
-
-
<EditText
-
android:id="@+id/et_path"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignParentLeft="true"
-
android:layout_alignParentRight="true"
-
android:layout_below="@+id/textView1"
-
android:ems="10"
-
android:inputType="none"
-
android:text="@string/et_path" >
-
-
<requestFocus />
-
</EditText>
-
-
<TextView
-
android:id="@+id/textView2"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignParentLeft="true"
-
android:layout_below="@+id/et_path"
-
android:text="@string/tv_threadNum" />
-
-
<EditText
-
android:id="@+id/et_threadNum"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignLeft="@+id/textView2"
-
android:layout_alignRight="@+id/et_path"
-
android:layout_below="@+id/textView2"
-
android:ems="10"
-
android:inputType="number"
-
android:text="@string/et_threadNum" />
-
-
<ProgressBar
-
android:id="@+id/pb_down"
-
style="?android:attr/progressBarStyleHorizontal"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignLeft="@+id/et_threadNum"
-
android:layout_alignRight="@+id/et_threadNum"
-
android:layout_below="@+id/et_threadNum"
-
android:layout_marginTop="14dp" />
-
-
<TextView
-
android:id="@+id/tv_pb"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignRight="@+id/textView1"
-
android:layout_below="@+id/pb_down"
-
android:layout_marginTop="24dp"
-
android:text="@string/tv_num" />
-
-
<Button
-
android:id="@+id/btn_down"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignLeft="@+id/pb_down"
-
android:layout_below="@+id/tv_pb"
-
android:layout_marginTop="32dp"
-
android:onClick="downLoad"
-
android:text="@string/btn_text" />
-
-
<Button
-
android:id="@+id/button1"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:layout_alignLeft="@+id/btn_down"
-
android:layout_below="@+id/btn_down"
-
android:layout_marginTop="16dp"
-
android:onClick="downPause"
-
android:text="@string/btn_pause" />
-
-
</RelativeLayout>
效果如下:

最后要注意的是别忘了在项目清单文件中加入权限:
安卓 下载多线程带进度条
原文:http://blog.csdn.net/kan1kan5/article/details/40166147