android多线程下载1

想做一个下载功能,当然理想的功能要支持多任务同时下载,断点续传的功能,我想一步一步来,首先困难摆在了多任务这里

开始我的思路是在一个Service中启动下载的流操作,然后通过Service中声明一个Activity中的Handler更新UI(比如进度条。。。)

可是我发现在Service中声明一个Activity中的Handler是做不到的(可能只是我做不到吧,无法申请内存)

于是,我决定在Activity中直接启动线程,让其运行,调用自身的Handler来更新UI,没想到在这个下载Activity onPause()的时候,线程还是活的,也就是说可以继续下载,下例是我做的一个两个任务同时下载的小例子,后面会把理想中的功能都陆续添加上的...

main.xml配置:

<?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="fill_parent"></ProgressBar> 
 
 <TextView android:layout_width="fill_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="fill_parent"></ProgressBar> 
 
 <TextView android:layout_width="fill_parent" android:id="@+id/textView2" 
 android:layout_height="wrap_content" /> 
</LinearLayout> 

AndroidManifest.xml配置:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
 package="sms.down" 
 android:versionCode="1" 
 android:versionName="1.0"> 
 <uses-sdk android:minSdkVersion="9" /> 
 
 <application android:icon="@drawable/icon" android:label="@string/app_name"> 
 <activity android:name=".MulThreadDownload" 
 android:label="@string/app_name"> 
 <intent-filter> 
 <action android:name="android.intent.action.MAIN" /> 
 <category android:name="android.intent.category.LAUNCHER" /> 
 </intent-filter> 
 </activity> 
 
 </application> 
 
 <!-- 访问 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"/> 
</manifest> 

activity程序:

package sms.down;  
 
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 MulThreadDownload 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;  
 
 private String root = Environment.getExternalStorageDirectory()  
            .getAbsolutePath() + File.separator;  
 private String downloadFile = "http://gongxue.cn/yingyinkuaiche/UploadFiles_9323/201008/2010082909434077.mp3";  
 private String downloadFile1 = "http://gongxue.cn/yingyinkuaiche/UploadFiles_9323/201008/2010082909434077.mp3";  
 
 // 声明已经读过的长度变量 
 private int hasRead = 0;  
 
 public void onCreate(Bundle savedInstanceState) {  
 super.onCreate(savedInstanceState);  
        setContentView(R.layout.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) {  
 // TODO Auto-generated catch block 
                    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) {  
 // TODO Auto-generated catch block 
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
 
        }  
    }  
 
}  

程序运行效果:

源码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏项勇

笔记19 | 利用MediaRecorder实现录像

22410
来自专栏何俊林

音视频的采集、编码、封包成 mp4 输出

使用 Android Camera API 完成音视频的采集、编码、封包成 mp4 输出 基于android.hardware.Camera,创建一个横屏应用,...

1544
来自专栏向治洪

gradeview可拖动效果实现

下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看) ? 一、开发心里历程 刚开始接触这个的时候,不知道要如何实...

3308
来自专栏刘望舒

LayoutInflater 布局渲染工具原理分析

LayoutInflater其实是一个布局渲染工具,其本质就只是一个工具,说白了LayoutInflater的作用就是根据xml布局文件构建View树,自定义...

1979
来自专栏一个会写诗的程序员的博客

第14章 使用Kotlin 进行 Android 开发(2)

我们使用 fastjson 来解析这个数据。在 app 下面的 build.gradle中添加依赖

982
来自专栏刘望舒

打造一个灵活易用的Banner组件

之前做项目时候出于各种考虑,自己开发了Banner组件FBanner,欢迎大家的Star和PR。github上成熟的轮播图库已经有非常多了,比如banner和A...

1255
来自专栏向治洪

SwipeListView实现仿ios的侧滑

github地址:https://github.com/xiangzhihong/SwipeMenuListView 今天介绍一个SwipeMenuListVi...

2508
来自专栏developerHaoz 的安卓之旅

Android 打造一个丝滑的自动轮播控件

现在很多的 App 都有自动轮播的 banner 界面,用于展示广告图片或者显示当前比较热门的一些活动,除了具备比较酷炫的效果之外,通过轮播的方式来减少对界面的...

1162
来自专栏指尖下的Android

Matisse预览图片黑屏,Glide内存溢出

项目中要到图片、视频选择的功能,然后google了一下,找到Matisse,知乎的图片选择框架,用的人还挺多的,果断依赖gradle,然后开始我的踩坑之旅。 ...

1931
来自专栏向治洪

Android开发模式之MVC,MVP和MVVM的简单介绍与区别

相信大家对MVC,MVP和MVVM都不陌生,作为三个最耳熟能详的Android框架,它们的应用可以是非常广泛的,但是对于一些新手来说,可能对于区分它们三个都有困...

1.1K8

扫码关注云+社区

领取腾讯云代金券