文档章节

安卓多线程下载 学习笔记

汤汤圆圆
 汤汤圆圆
发布于 2015/06/14 17:45
字数 704
阅读 10
收藏 0
点赞 0
评论 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
博文 63
码字总数 18884
作品 0
昌平
程序员
张高兴的 Xamarin.Android 学习笔记:(一)环境配置

  最近在自学 Xamarin 和 Android ,同时发现国内在做 Xamarin 的不多。我在自学中间遇到了很多问题,而且百度到的很多教程也有些过时,现在打算写点东西稍微总结下,顺便帮后人指指路了。...

张高兴 ⋅ 2017/01/13 ⋅ 0

Android性能优化:手把手教你如何让App更快、更稳、更省(含内存、布局优化等)

前言 在 开发中,性能优化策略十分重要 因为其决定了应用程序的开发质量:可用性、流畅性、稳定性等,是提高用户留存率的关键 本文全面讲解性能优化中的所有知识,献上一份 性能优化的详细攻...

Carson_Ho ⋅ 05/30 ⋅ 0

腾讯X5WebView集成2018-05-15

工作中经常偶尔会用到H5网页来加载页面,使用原生的Android的WebView可以加载,但是当网页内容比较多的时候,需要等待很久才能加载完,加载完后用户才能看到网页中的内容,这样用户需要等很久...

林灬 ⋅ 05/15 ⋅ 0

安卓系统下的多线程断点下载实现

最近研究多线程下载,写了个demo,整理下来,也许会对别人有帮助。 多线程下载的话一般开启两到三个线程吧。如果线程太多的话时间会浪费在线程的切换上,倒是浪费了大把的时间。线程多了也不...

rootusers ⋅ 2015/03/17 ⋅ 0

读书笔记--Android Gradle权威指南(上)

最近看了一本书《Android Gradle 权威指南》,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所以打算写一篇读书笔记,将书中一些我个人觉得蛮有用的点记录、总结一下。 前言 首先,...

请叫我大苏 ⋅ 05/24 ⋅ 0

Google让Chromebook用户在Chrome OS中管理所有Android文件

Google Chromium开发者FrançoisBeaufort透露,Chrome操作系统团队正计划在Files应用中让Chromebook设备管理所有的Android文件。被称为“Android文件”的新功能已在Chrome OS Dev频道中实施,...

稿源:cnBeta.COM ⋅ 06/04 ⋅ 0

Android性能优化:关于 内存泄露 的知识都在这里了!

前言 在中,内存泄露的现象十分常见;而内存泄露导致的后果会使得应用 本文 全面介绍了内存泄露的本质、原因 & 解决方案,最终提供一些常见的内存泄露分析工具,希望你们会喜欢。 目录 } Li...

Carson_Ho ⋅ 04/19 ⋅ 0

React-Native 之 环境配置和简单使用

前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所偏差,在...

postdep ⋅ 05/01 ⋅ 0

[RK3288][Android6.0]调试笔记 --- Failed to resolve: com.android.support:appcompat-v7:27

Platform: RK3288 OS: Android 6.0 Kernel: 3.10.92 l现象: 重新安装一个新的Android Studio后,每次新建工程,总是提示: 如图: 点击并没有成功。 原因: 解决方法: 方法一: 直接修改b...

kris_fei ⋅ 04/24 ⋅ 0

Android RxJava:这是一份RxJava使用入门学习指南

前言 由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 开发者的欢迎。 如果还不了解RxJava,请看文章:Android:这是一篇 清晰 & 易懂的Rxjava 入门教程 今天,我将为初学...

Carson_Ho ⋅ 06/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

知乎Java数据结构

作者:匿名用户 链接:https://www.zhihu.com/question/35947829/answer/66113038 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 感觉知乎上嘲讽题主简...

颖伙虫 ⋅ 今天 ⋅ 0

Confluence 6 恢复一个站点有关使用站点导出为备份的说明

推荐使用生产备份策略。我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 home 目录)。XML 导出备...

honeymose ⋅ 今天 ⋅ 0

JavaScript零基础入门——(九)JavaScript的函数

JavaScript零基础入门——(九)JavaScript的函数 欢迎回到我们的JavaScript零基础入门,上一节课我们了解了有关JS中数组的相关知识点,不知道大家有没有自己去敲一敲,消化一下?这一节课,...

JandenMa ⋅ 今天 ⋅ 0

火狐浏览器各版本下载及插件httprequest

各版本下载地址:http://ftp.mozilla.org/pub/mozilla.org//firefox/releases/ httprequest插件截至57版本可用

xiaoge2016 ⋅ 今天 ⋅ 0

Docker系列教程28-实战:使用Docker Compose运行ELK

原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: version: '2'services: ...

周立_ITMuch ⋅ 今天 ⋅ 0

使用快嘉sdkg极速搭建接口模拟系统

在具体项目研发过程中,一旦前后端双方约定好接口,前端和app同事就会希望后台同事可以尽快提供可供对接的接口方便调试,而对后台同事来说定好接口还仅是个开始、设计流程,实现业务逻辑,编...

fastjrun ⋅ 今天 ⋅ 0

PXE/KickStart 无人值守安装

导言 作为中小公司的运维,经常会遇到一些机械式的重复工作,例如:有时公司同时上线几十甚至上百台服务器,而且需要我们在短时间内完成系统安装。 常规的办法有什么? 光盘安装系统 ===> 一...

kangvcar ⋅ 昨天 ⋅ 0

使用Puppeteer撸一个爬虫

Puppeteer是什么 puppeteer是谷歌chrome团队官方开发的一个无界面(Headless)chrome工具。Chrome Headless将成为web应用自动化测试的行业标杆。所以我们很有必要来了解一下它。所谓的无头浏...

小草先森 ⋅ 昨天 ⋅ 0

Java Done Right

* 表示难度较大或理论性较强。 ** 表示难度更大或理论性更强。 【Java语言本身】 基础语法,面向对象,顺序编程,并发编程,网络编程,泛型,注解,lambda(Java8),module(Java9),var(...

风华神使 ⋅ 昨天 ⋅ 0

Linux系统日志

linux 系统日志 /var/log/messages /etc/logrotate.conf 日志切割配置文件 https://my.oschina.net/u/2000675/blog/908189 logrotate 使用详解 dmesg 命令 /var/log/dmesg 日志 last命令,调......

Linux学习笔记 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部