效果图

下载文件:

讲解: 多线程下载多个文件:
下载首先就必须明白http协议,不会的读者:请点击这里
首先我们知道关于操作网络我们是不能直接在UI(主)线程中直接操作的,所以这里我们就得开启线程
在主线程调用的时候new多次开启的线程,就实现了线程,然后在每个线程中进行网络操作,这就是所谓的多线程下载多个文件。

1.首先在manifest中加入网络,允许读取文件等权限:

    <!-- 访问 internet 权限 --><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.CALL_PHONE" /><uses-permission android:name="android.permission.SEND_SMS" /><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><uses-permission android:name="android.permission.READ_PHONE_STATE"/>

2.activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent"><ProgressBar style="?android:attr/progressBarStyleHorizontal"android:layout_height="wrap_content" android:id="@+id/progressBar1"android:layout_width="match_parent"></ProgressBar><TextView android:layout_width="match_parent" android:id="@+id/textView1"android:layout_height="wrap_content" /><ProgressBar style="?android:attr/progressBarStyleHorizontal"android:layout_height="wrap_content" android:id="@+id/progressBar2"android:layout_width="match_parent"></ProgressBar><TextView android:layout_width="match_parent" android:id="@+id/textView2"android:layout_height="wrap_content" />
</LinearLayout>

3.MainActivity:


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;public class MainActivity extends Activity {/** Called when the activity is first created. */private ProgressBar pb1 = null;private TextView tv1 = null;private ProgressBar pb2 = null;private TextView tv2 = null;//得到SD的路径绝对路径private String root = Environment.getExternalStorageDirectory();//下载地址1private String downloadFile = "http://gongxue.cn/yingyinkuaiche/UploadFiles_9323/201008/2010082909434077.mp3";//下载地址2private String downloadFile1 = "http://gongxue.cn/yingyinkuaiche/UploadFiles_9323/201008/2010082909434077.mp3";public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);pb1 = (ProgressBar) findViewById(R.id.progressBar1);tv1 = (TextView) findViewById(R.id.textView1);pb2 = (ProgressBar) findViewById(R.id.progressBar2);tv2 = (TextView) findViewById(R.id.textView2);download(downloadFile, root, pb1, tv1);download(downloadFile1, root, pb2, tv2);}private void download(String url, String targetPath, ProgressBar pb,TextView tv) {DownloadThread dt = new DownloadThread(url, targetPath, pb, tv);//线程开始,下载开始dt.start();}/***  自定义一个Handler类,处理线程消息*/public class MyHandler extends Handler {private ProgressBar progressBar;private TextView textView;// 通过构造函数来确定给哪个ProgressBar刷新public MyHandler(ProgressBar progressBar, TextView textView) {this.progressBar = progressBar;this.textView = textView;}public void handleMessage(Message msg) {this.progressBar.setProgress(msg.arg1);this.textView.setText(msg.arg1 + "%");super.handleMessage(msg);}}// 下载线程public class DownloadThread extends Thread {private String url = "";//下载地址private String targetPath = "";//目标路径private int hasDownload = 0; //已经下载的长度private int len = -1;private byte buffer[] = new byte[4 * 1024];private int size = 0; //文件的长度private int rate = 0;//所占的百分比private MyHandler myHandler = null;private Message msg = null;private ProgressBar pb = null;private TextView tv = null;public DownloadThread(String url, String targetPath, ProgressBar pb,TextView tv) {this.url = url;this.targetPath = targetPath;this.pb = pb;this.tv = tv;myHandler = new MyHandler(this.pb, this.tv);}public void run() {//   目标路径/文件名String targetFileName = this.targetPath+ this.url.substring(this.url.lastIndexOf("/") + 1,this.url.length());//文件对象File downloadFile = new File(targetFileName);if (!downloadFile.exists()) {try {downloadFile.createNewFile();} catch (IOException e) {e.printStackTrace();}}try {URL fileUrl = new URL(this.url);HttpURLConnection conn = (HttpURLConnection) fileUrl.openConnection();// 获取文件大小size = conn.getContentLength();InputStream is = conn.getInputStream();OutputStream os = new FileOutputStream(targetFileName);while ((len = is.read(buffer)) != -1) {os.write(buffer);hasDownload += len;rate = (hasDownload * 100 / size);msg = new Message();msg.arg1 = rate;myHandler.sendMessage(msg);System.out.println(rate + "%");}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}}

Android基础篇-多线程下载(一)相关推荐

  1. 【建议收藏】2020年中高级Android大厂面试秘籍,为你保驾护航金三银四,直通大厂(Android基础篇)...

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. A awesome android expert interview questions a ...

  2. android各目录大小,Android 基础篇 — 放不同drawable文件夹中图片的大小

    我们接着上篇文章Android 基础篇 - 不同DPI取哪个本地文件夹中的资源 讲,文末尾提到一个问题,为什么不同drawable文件夹中的图片大小在终端设备会不一样? 1 准备 在drawable- ...

  3. Android基础篇 屏幕横竖屏切换(layout-land)下篇

    默认情况下Activity进行屏幕旋转会自动进行onDestroy并重新onCreate 一.非默认情况下 在AndroidManifest.xml的Activity中配置 <activitya ...

  4. Android 基础篇之环境配置

    Android接触也有半年了本来是打算一年后开始写博客,现在写的话显得有点班门弄斧的感觉,但是听到几个前辈们教导,还是现在养成这个好习惯吧, 因为才刚刚接触半年,也不算什么大神大牛 ,所以这几篇博客只 ...

  5. Android基础篇-五大存储方式之一数据库存储

    废话不多说,直接看代码 activity_main: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/a ...

  6. 【Android基础】多线程编程

    介绍 当我们需要执行一些耗时操作时,比如发起一条网络请求,考虑到网速等因素的影响,服务器未必会立即响应我们的请求,如果不将这类操作放到子线程中去运行,会导致主线程被阻塞,从而影响用户对软件的正常使用. ...

  7. 2020年中高级Android面试秘籍(Android基础篇)

    转载:https://juejin.im/post/5e5c5e306fb9a07cbe346d71 前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的 ...

  8. Android基础篇(四)

    AdapterView 指使用适配器来配置多个内容显示的视图,代表的有ListView(列表).GridView(九宫格).ExpanableListView(分组列表) ListView <L ...

  9. Java基础篇--多线程之第一个线程用来计算2~100000之间的素数的个数,第二个线程用来计算100000~200000之间的素数的个数

    多线程操作: 编写一个有两个线程的程序,第一个线程用来计算2-100000之间的素数的个数,第二个线程用来计算100000-200000之间的素数的个数,最后输出结果. 1.判断是否为素数的方法: 是 ...

最新文章

  1. SCOI 2014 new :未来展望
  2. 原生JS字符串操作方法汇总
  3. 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contai
  4. Cow Contest(POJ-3660 )
  5. c语言加速度积分得到速度_自编微积分教材-第一章 微积分漫谈(1)
  6. 引导linux为什么要用实模式,Linux引导过程与故障排除|第1章:Linux启动流程详解...
  7. php pop3,php使用smtp,pop3协议收发邮件代码
  8. ABAP术语-Update Task
  9. 把Oracle数据库移植到Microsoft SQL Server 7.0
  10. php 微信公众号客服,微信公众平台开发多客服
  11. JSCore浅析及其在iOS上的使用
  12. 由QCustomplot引发drawPolyline和drawLine的区别
  13. js/vue 动态获取浏览器宽度/高度
  14. 基于数字孪生的IBV智能建筑可视化系统了解一下
  15. php notice错误是什么意思,PHP中Notice错误常见解决方法
  16. 一:log4j2配置文档
  17. 阿里云通信发布全新号码认证服务, 重新定义手机号码认证的方式
  18. 基于android的互动健身平台,基于Android和ARM的智能健身系统的设计与实现
  19. vue项目 - Mockjs 模拟后台接口数据
  20. ios友盟错误_iOS - 友盟错误分析

热门文章

  1. Eclipse 出现none applicable问题
  2. Java的三魂七魄 —— 高级多线程
  3. PHP系列 | 不要在循环体中使用 array_merge()
  4. 古哥的 IT 职场历程
  5. linux superblock位置,Linux下恢复EXT3 Superblock的正确方法
  6. 浅析JAVA的HashMap(JDK1.8)
  7. http 404 badRequest
  8. linux驱动获取函数失败信息,linux驱动调试--段错误之栈信息分析
  9. 关键字:strictfp
  10. 中国十大女性网站排行榜