AsyncTask异步实现文件下载

做android开发的都知道,我们在主线程中不能进行耗时太久的操作,否则就可能报ANR,所有耗时的操作都要异步进行。android中的异步方法也很多,可以用Handler,可以用Thread及Runnable等。今天我们用安卓自带的异步工具AsyncTask来实现耗时操作:从网络下载文件。先对AsyncTask作个简单的介绍,下面的介绍也主要是参考网上资料:

1,AsyncTask定义了三种泛型类型 Params,Progress和Result。

  • Params 启动任务执行的输入参数,如网络请求的URL。
  • Progress 后台进行中任务执行进度百分比。
  • Result 后台执行任务完成最终返回的结果,比如String,Bitmap等。

2,使用AsyncTask 最少要重写以下这两个方法:

  • doInBackground(Params…) 后台执行,耗时的操作都可以放在这里(这里不能直接操作UI)。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度,并用进度条显示出来。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回。

3,有进我还需要重写以下这三个方法(非必需):

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()   用户调用取消时,要做的操作可以放到这里面处理。

4,使用AsyncTask类,以下是几条必须遵守的准则:

  • AsyncTask的实例和execute方法必须在UI线程中创建,
  • 不要手动调用onPreExecute(), onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)这4个方法,
  • 该实现的AsyncTask只能被执行一次,否则多次调用时将会出现异常;                                                          
      下面是我们实现文件下载的例子:
  • 布局:
  • <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    <Button

    android:id="@+id/file_download_btn"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:gravity="center"

    android:textSize="16sp"

    android:text="下载文件" />

    </LinearLayout>

  • Activity代码:
  • public class MainActivity extends Activity implements OnClickListener {

    /* SD卡根目录 */

    private File rootDie;

    /* 输出文件名称 */

    private String outFileName = "ldm.rar";

    /* 进度条对话框 */

    private ProgressDialog pdialog;

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    checkAndCreateDir();

    findViewById(R.id.file_download_btn).setOnClickListener(this);

    }

    @Override

    protected Dialog onCreateDialog(int id) {

    /* 实例化进度条对话框 */

    pdialog = new ProgressDialog(this);

    /* 进度条对话框属性设置 */

    pdialog.setMessage("正在下载中...");

    /* 进度值最大100 */

    pdialog.setMax(100);

    /* 水平风格进度条 */

    pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

    /* 无限循环模式 */

    pdialog.setIndeterminate(false);

    /* 可取消 */

    pdialog.setCancelable(true);

    /* 显示对话框 */

    pdialog.show();

    return pdialog;

    }

    /* 检查sdcard并创建目录文件 */

    private void checkAndCreateDir() {

    /* 获取sdcard目录 */

    rootDie = Environment.getExternalStorageDirectory();

    /* 新文件的目录 */

    File newFile = new File(rootDie + "/download/");

    if (!newFile.exists()) {

    /* 如果文件不存在就创建目录 */

    newFile.mkdirs();

    }

    }

    /* 异步任务,后台处理与更新UI */

    class MyLoadAsyncTask extends AsyncTask<String, String, String> {

    /* 后台线程 */

    @Override

    protected String doInBackground(String... params) {

    /* 所下载文件的URL */

    try {

    URL url = new URL(params[0]);

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    /* URL属性设置 */

    conn.setRequestMethod("GET");

    /* URL建立连接 */

    conn.connect();

    /* 下载文件的大小 */

    int fileOfLength = conn.getContentLength();

    /* 每次下载的大小与总下载的大小 */

    int totallength = 0;

    int length = 0;

    /* 输入流 */

    InputStream in = conn.getInputStream();

    /* 输出流 */

    FileOutputStream out = new FileOutputStream(new File(rootDie + "/mydownload1/", outFileName));

    /* 缓存模式,下载文件 */

    byte[] buff = new byte[1024 * 1024];

    while ((length = in.read(buff)) > 0) {

    totallength += length;

    String str1 = "" + (int) ((totallength * 100) / fileOfLength);

    publishProgress(str1);

    out.write(buff, 0, length);

    }

    /* 关闭输入输出流 */

    in.close();

    out.flush();

    out.close();

    } catch (MalformedURLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return null;

    }

    /* 预处理UI线程 */

    @Override

    protected void onPreExecute() {

    showDialog(0);

    super.onPreExecute();

    }

    /* 结束时的UI线程 */

    @Override

    protected void onPostExecute(String result) {

    dismissDialog(0);

    super.onPostExecute(result);

    }

    /* 处理UI线程,会被多次调用,触发事件为publicProgress方法 */

    @Override

    protected void onProgressUpdate(String... values) {

    /* 进度显示 */

    pdialog.setProgress(Integer.parseInt(values[0]));

    }

    }

    @Override

    public void onClick(View v) {

    if (v.getId() == R.id.file_download_btn) {

    /* 异步下载 */

    new MyLoadAsyncTask().execute("http://192.168.1.105:8080/tool.rar");

    }

    }

    }

  • 最后别忘记在AndroidManifest.xml中加上权限:
  • <!-- sdcard读写权限 -->

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!-- sdcard创建目录与文件权限 -->

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <!-- 网络访问权限 -->

    <uses-permission android:name="android.permission.INTERNET" />

时间: 2024-10-05 02:38:46

AsyncTask异步实现文件下载的相关文章

Android异步处理二:使用AsyncTask异步更新UI界面

Android异步处理二:使用AsyncTask异步更新UI界面 - lzc的专栏 - 博客频道 - CSDN.NET 在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简洁的实现方式:使用AsyncTask异步更新UI界面. 概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的

Android多线程分析之五:使用AsyncTask异步下载图像

Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<Android多线程分析之中的一个:使用Thread异步下载图像>中.曾演示了怎样使用 Thread 来完毕异步任务. Android 为了简化在 UI 线程中完毕异步任务(毕竟 UI 线程是 app 最重要的线程).实现了一个名为 AysncTask 的模板类.使用 AysncTask 能够在异步任务进行的同

asyncTask异步任务:从网络下载图片

[关键字]:3个参数,4个步骤 第一步:表示任务执行前的操作 第二步:主要完成耗时操作 第三步:主要是更新UI操作 第四步:产生最终结果 以下实例中代表的含义为: 第一步:显示进度条 第二步:(此任务必不可少)在后台执行任务,将进度值传给第三步,将结果传给第四步: 第三步:进度值更新 第四步:产生最终结果 1.添加网络授权: 因为手机默认不能访问网络,所以首先要在清单文件 AndroidManifest.xml中添加网络授权. 方法如下: 打开AndroidManifest.xml文件,点击"P

AsyncTask 异步线程 用法

AsyncTask介绍Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理.首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的.Android为了降低这个开发难度,提供了AsyncTask.AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务.AsyncTask直接继承于Object类,位置为android.os.AsyncTask.要使用Asy

Android AsyncTask异步任务

在上一篇文章<Android网络编程之使用HttpClient进行Get方式通信>中,我们强制直接在UI线程进行网络操作,在实际的应用开发过程中不能这样做,因为这样很可能会阻塞UI,影响用户体验.为了避免直接在UI线程中进行网络操作,我们可以使用AsyncTask异步处理网络通信和UI更新.通过AysncTask可以很容易的启动后台线程进行网络通信,然后将结果返回到UI线程中. AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接

Android异步更新UI的方式之使用AsyncTask异步任务

由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中更新UI,给大家介绍一种方式:使用AsyncTask异步任务. 下面用这种方式更新一个TextView: 注:更新UI的操作只能在onPostExecute(String result)方法中. package com.example.runonuithreadtest;  import android.app.Activity;  import android.os.AsyncTask;  import android.

Android线程管理之AsyncTask异步任务(四)

前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 产生背景: 我们都知道Android应用程序是单线程模型,在子线程无法直接操作UI主线程,必须通过Handler机制,想了解这方面的知识可以参考这篇文章:Android消息传递之Handler消息机制(一),所以基于这种考虑所以我们一般情况会采用Thread+Handler来处理比较耗时的操作,但是我们都知道

Android中使用Thread线程与AsyncTask异步任务的区别

最近和几个朋友交流Android开发中的网络下载问题时,谈到了用Thread开启下载线程时会产生的Bug,其实直接用子线程开启下载任务的确是很Low的做法,那么原因究竟如何,而比较高大上的做法是怎样?于是用这篇博文详细分析记录一下. 一.概念介绍 Thread是指在CPU运行的一个程序中,可以有多个执行路径.运行的程序称作进程,而这个执行路径,就被称为线程(如果对这两个名词不太理解的同学可以参考一下操作系统方面的书籍).Java中的多线程是指多个Thread可以在一段内同步执行,这样可以提高代码

AsyncTask异步任务 源码解读

之前我们介绍了Handler的一些基本用法,也解读了Handler的源码.通过Handler我们可以简便的切换到主线程进行UI操作.而AsyncTask的出现使我们不用去关心线程管理和切换的一些细节,我们可以更轻松的去操作UI. 基本概念 AsyncTask异步任务的作用 AsyncTask,见名之意,异步任务.允许我们在后台做一些耗时操作,然后切换到主线程更新,而且这一过程变得非常简便.一提到异步任务,我们的第一反应就是多线程.假如我们现在需要去下载一张图片,然后在界面上显示,如果没有Asyn