博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安卓实训第七天---多线程下载实现(进度条)
阅读量:6271 次
发布时间:2019-06-22

本文共 8676 字,大约阅读时间需要 28 分钟。

 
 
 
 
 
 
 
 
 
packagecom.example.download;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;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.Environment;import android.os.Handler;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 {	// 定义正在执行的线程	private int threadRunning = 3;	// 线程开启的数量	private int threadNum = 3;	private EditText et_url;	// 进度条	private ProgressBar progressBar;	private TextView tv_pb;	private int currentProgress = 0;	private 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_url);		progressBar = (ProgressBar) findViewById(R.id.tv_jindu);		tv_pb = (TextView) findViewById(R.id.tv_pb);		File sdDir = Environment.getExternalStorageDirectory();		File pdFile = new File(sdDir, "pb.txt");		InputStream is = null;		try {			if (pdFile.exists()) {				is = new FileInputStream(pdFile);			}		} catch (FileNotFoundException e) {			e.printStackTrace();		}		if (is != null) {			String value = StreamTools.streamTostr(is);			String arr[] = value.split(";");			progressBar.setMax(Integer.valueOf(arr[0]));// 最大值			currentProgress = Integer.valueOf(arr[1]);// 当前值			progressBar.setProgress(currentProgress);			;			tv_pb.setText("当前的进度是" + arr[2] + "%");		}	}	public void downLoadFile(View v) {		// 訪问地址:		final String spec = et_url.getText().toString();// "http://172.16.237.144:8080/Login/football.jpg";		if (TextUtils.isEmpty(spec)) {			Toast.makeText(this, "下载地址不能为空", Toast.LENGTH_LONG).show();		} else {			new Thread() {				public void run() {					try {						URL url = new URL(spec);						HttpURLConnection httpURLConnection = (HttpURLConnection) url								.openConnection();						// 设置请求的头文件信息还有时间						httpURLConnection.setRequestMethod("GET");						httpURLConnection.setConnectTimeout(5000);						httpURLConnection.setReadTimeout(5000);						if (httpURLConnection.getResponseCode() == 200) {							int fileLength = httpURLConnection									.getContentLength();							// 设置进度条的最大值							progressBar.setMax(fileLength);							// 推断你的设备SDCard是否可用							if (Environment.getExternalStorageState().equals(									Environment.MEDIA_MOUNTED)) {								// 外部存储设备的路径								File sdfile = Environment										.getExternalStorageDirectory();								// 获取文件的名称								String fileName = spec.substring(spec										.lastIndexOf("/") + 1);								// 创建保存的文件								File file = new File(sdfile, fileName);								// 创建随机能够訪问的文件对象								RandomAccessFile accessFile = new RandomAccessFile(										file, "rwd");								// 设置文件大小								accessFile.setLength(fileLength);								// 关闭操作								accessFile.close();								// 首先计算出每一个线程下载的大小 開始位置 结束位置								int threadSize = fileLength / threadNum;								// for循环开启线程处理								for (int threadId = 1; threadId <= 3; threadId++) {									int startIndex = (threadId - 1)											* threadSize;// 開始位置									int endIndex = threadId * threadSize - 1;									if (threadId == threadNum) {// 最后一个线程										endIndex = fileLength - 1;									}									System.out.println("当前线程--" + threadId											+ "開始位置---" + startIndex											+ "结束位置---" + endIndex + "线程大小---");									// 开启线程下载要用Start方法									new DownLoadThread(threadId, startIndex,											endIndex, spec, fileName).start();								}							} else {								MainActivity.this.runOnUiThread(new Runnable() {									@Override									public void run() {										Toast.makeText(MainActivity.this,												"设备的SD卡不可用", Toast.LENGTH_LONG)												.show();									}								});							}						} else {							// 这里用这个能够让它在主线程中执行							MainActivity.this.runOnUiThread(new Runnable() {								@Override								public void run() {									Toast.makeText(MainActivity.this,											"server端返回错误", Toast.LENGTH_LONG)											.show();								}							});						}					} catch (Exception e) {						e.printStackTrace();					}				};			}.start();		}	}	class DownLoadThread extends Thread {		private int threadId;		private int startIndex;		private int endIndex;		private String path;		private String fileName;		public DownLoadThread(int threadId, int startIndex, int endIndex,				String path, String fileName) {			super();			this.threadId = threadId;			this.startIndex = startIndex;			this.endIndex = endIndex;			this.path = path;			this.fileName = fileName;		}		@Override		public void run() {			// 能够通过每一个线程去下载文件了。			try {				File sdfile = Environment.getExternalStorageDirectory();				// 获取每一个线程下载的记录文件				File recordFile = new File(sdfile, threadId + ".txt");				// 推断记录文件是否存在				if (recordFile.exists()) {					// 读取文件的内容					InputStream is = new FileInputStream(recordFile);					// 利用工具类转换					String value = StreamTools.streamTostr(is);					// 获取记录位置					int recordIndex = Integer.parseInt(value);					// 记录的位置复制给開始的位置就可以					startIndex = recordIndex;				}				// 通过path路径构建URL对象				URL url = new URL(path);				// 通过URL对象的打开连接,返回对象				HttpURLConnection httpURLConnection = (HttpURLConnection) url						.openConnection();				// 设置请求头				httpURLConnection.setRequestMethod("GET");				httpURLConnection.setConnectTimeout(5000);				// 设置下载文件的開始位置和结束位置				httpURLConnection.setRequestProperty("Range", "bytes="						+ startIndex + "-" + endIndex);				// 获取的状态吗				int code = httpURLConnection.getResponseCode();				if (code == 206) {					// 获取每一个线程返回的流对象:					InputStream inputStream = httpURLConnection							.getInputStream();					// 获取文件名 由于已经通过那边传过来了					// String fileName =					// path.substring(path.lastIndexOf("/")+1);					// 外部存储设备的路径					File file = new File(sdfile, fileName);					// 依据文件创建她RandomAccessFile对象					RandomAccessFile raf = new RandomAccessFile(file, "rwd");					raf.seek(startIndex);					// 定义读取的长度					int len = 0;					byte buffer[] = new byte[50];					int total = 0;					// 循环读取					while ((len = inputStream.read(buffer)) != -1) {						System.out.println("当前线程--" + threadId + "--已经下载了"								+ (startIndex + total));						// 创建线程下载记录的文件						RandomAccessFile threadfile = new RandomAccessFile(								new File(sdfile, threadId + ".txt"), "rwd");						threadfile.writeBytes((startIndex + total) + "");						threadfile.close();						raf.write(buffer, 0, len);						total += len;						synchronized (MainActivity.this) {							currentProgress += len;							progressBar.setProgress(currentProgress);							// 计算百分比的操作 int							final String percent = currentProgress * 100L									/ progressBar.getMax() + "";							MainActivity.this.runOnUiThread(new Runnable() {								@Override								public void run() {									tv_pb.setText("当前的进度是:" + percent + "%");								}							});							RandomAccessFile pbfile = new RandomAccessFile(									new File(sdfile, "pb.txt"), "rwd");							pbfile.writeBytes(progressBar.getMax() + ";"									+ currentProgress + ";" + percent);							pbfile.close();						}					}					raf.close();					inputStream.close();					MainActivity.this.runOnUiThread(new Runnable() {						@Override						public void run() {							// System.out.println("当前线程----"+threadId+"完成下载");							Toast.makeText(MainActivity.this,									"当前线程----" + threadId + "完成下载",									Toast.LENGTH_LONG).show();						}					});					deleteRecordFiles();				} else {					MainActivity.this.runOnUiThread(new Runnable() {						@Override						public void run() {							Toast.makeText(MainActivity.this, "server端下载错误",									Toast.LENGTH_LONG).show();						}					});				}			} catch (Exception e) {				e.printStackTrace();			}		}	}	public synchronized void deleteRecordFiles() {		File sdfile = Environment.getExternalStorageDirectory();		System.out.println("-------------------------");		threadRunning--;		if (threadRunning == 0) {			for (int i = 1; i <= 3; i++) {				File recordFile = new File(sdfile, i + ".txt");				if (recordFile.exists()) {					boolean flag1 = recordFile.delete();// 删除掉文件					System.out.println("下载记录" + i + "文件已" + flag1 + "删除");				}				File pdFile = new File(sdfile, "pb.txt");				if (pdFile.exists()) {					boolean flag2 = pdFile.delete();					System.out.println("进度条记录文件已" + flag2 + "删除");				}			}		}	}	public void displayMsg() {	}}

BUG注意事项:

1、继续线程下载的文件一定要运行threadfile.close(),不然就无法运行后面的删除TXT文件部分。

2、一定要注意下载速度的设置,不能太快。超过传输文件的大小。不然会导致模拟器死掉。;

转载地址:http://pklpa.baihongyu.com/

你可能感兴趣的文章
新年第一镖
查看>>
unbtu使用笔记
查看>>
MaxCompute 学习计划(一)
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
Android程序开发初级教程(一) 开始 Hello Android
查看>>
使用Gradle打RPM包
查看>>
“我意识到”的意义
查看>>
淘宝天猫上新辅助工具-新品填表
查看>>
再学 GDI+[43]: 文本输出 - 获取已安装的字体列表
查看>>
nginx反向代理
查看>>
操作系统真实的虚拟内存是什么样的(一)
查看>>
hadoop、hbase、zookeeper集群搭建
查看>>
python中一切皆对象------类的基础(五)
查看>>
modprobe
查看>>
android中用ExpandableListView实现三级扩展列表
查看>>
%Error opening tftp://255.255.255.255/cisconet.cfg
查看>>
java读取excel、txt 文件内容,传到、显示到另一个页面的文本框里面。
查看>>
《从零开始学Swift》学习笔记(Day 51)——扩展构造函数
查看>>
python多线程队列安全
查看>>
[汇编语言学习笔记][第四章第一个程序的编写]
查看>>