文档章节

安卓多线程下载 学习笔记

汤汤圆圆
 汤汤圆圆
发布于 2015/06/14 17:45
字数 704
阅读 10
收藏 0
布局文件
<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文件


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"/>





© 著作权归作者所有

共有 人打赏支持
汤汤圆圆

汤汤圆圆

粉丝 11
博文 72
码字总数 23220
作品 0
昌平
程序员
一份关于 Java、Kotlin 与 Android 的学习笔记

JavaKotlinAndroidLearn 这是一份关于 Java 、Kotlin 、Android 的学习笔记,既包含对基础知识点的介绍,也包含对一些重要知识点的源码解析,笔记的大纲如下所示: Java 重拾Java(0)-基础知...

叶应是叶
08/08
0
0
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
第一天学习Android的一些笔记

昨天学习了怎样装Android配置环境,下载SDK用了好久的时间,再加上一开始不会,弄了好长时间,今天第一天学习,跟着视频教程学的。下边是我的一些笔记,仅做留念与学习笔记 。 快捷键: 智能...

子弹兄
2014/01/16
0
0
Android adt bundle 开发环境配置及第一个“Hello world”程序运行

最近在学习Android 顺便记录下学习过程当作复习吧,这是写的第一篇正式博客。 一、jdk环境配置 二、android adt bundle 下载 三、安装SDK 四、模拟器及真机调试 五、第一个程序 Hello world!...

程序猿付显
2014/07/23
0
0
一个老鸟发的公司内部整理的 Android 学习路线图

一个老鸟发的公司内部整理的 Android 学习路线图 jixiaohua发了一篇。另一份 Android 开发学习路线图。可惜不是MarkDown格式的,所以jixiaohua直接上传的截图,在jixiaohua的呼吁下,我花了些...

2eggs
08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

企业级 SpringBoot教程(三)SpringBoot用JdbcTemplates访问Mysql

准备工作 jdk 1.8 maven 3.0 idea mysql 初始化mysql: -- create table `account`DROP TABLE `account` IF EXISTSCREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT,......

itcloud
27分钟前
1
0
事务的作用

1. 什么是事务,为什么使用事务? 一、概念: 1.数据库事务: 数据库事务通常指对数据库进行读或写的一个操作序列。 它的存在包含有以下两个目的: 1、为数据库操作提供了一个从失败中恢复到正常...

gaomq
28分钟前
1
0
Web工程师以太坊入门

我经常构建使用以太坊的Web应用程序,我理所当然地认为每天都使用的是神奇的工具集。我们的生态系统正在迅速发展,我认为很多新人都感到不知所措。以太坊是一项了不起的技术,但它也是新生的...

geek12345
30分钟前
0
0
新蠕虫出现:以Linux和Windows为目标

正如Unit 42研究团队所详述的那样,名为Xbash的新恶意软件系列与Iron Group有关,Iron Group是一个以前知道可以执行勒索软件攻击的威胁行为者,显然已经转向更复杂的攻击媒介。 据观察,Xba...

linux-tao
33分钟前
0
0
Mask 动画

前言:很多动效都是多种动画的组合,有时候你可能只是需要其中某个动画,但面对庞杂的代码库或是教程,你可能比较困惑,本系列将复杂动效中不常见的动画效果拆解出来便于学习,授人以鱼不如授...

walking_yxf
34分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部