`
iaiai
  • 浏览: 2196988 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android AsyncTask实现异步任务的执行

 
阅读更多
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。

首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。

Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。

AsyncTask 的优势体现在:
  • 线程的开销较大,如果每个任务都要创建一个线程,那么应用程 序的效率要低很多;
  • 线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。
  • 另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。


AsyncTask定义了三种泛型类型 Params,Progress和Result。
  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。


AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现一个或几个方法。在任务的执行过程中,这些方法被自动调用。

onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。

doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。

onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

使用AsyncTask类,以下是几条必须遵守的准则:
  • Task的实例必须在UI thread中创建
  • execute方法必须在UI thread中调用
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  • 该task只能被执行一次,否则多次调用时将会出现异常


一个简单进度条的例子:
<?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 android:id="@+id/progress_bar" 
    android:layout_width="200dip" android:layout_height="10dip" 
     android:layout_gravity="center" 
    android:max="100" style="?android:attr/progressBarStyleHorizontal" 
    android:progress="0"> 
  </ProgressBar> 

</LinearLayout>


import android.app.Activity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.widget.ProgressBar; 

public class Double extends Activity { 

  public ProgressBar pBar; 

  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    pBar = (ProgressBar) findViewById(R.id.progress_bar); 
    //AsyncTask.execute()要在主线程里调用 
    new AsyncLoader().execute((Void)null); 
  } 

  public void initProgress() { 
    pBar.setProgress(0); 
    try { 
      Thread.sleep(1000); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
    pBar.setProgress(50); 
    try { 
      Thread.sleep(1000); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
    pBar.setProgress(100);  
  } 
    
  //AsyncTask 
  class AsyncLoader extends AsyncTask<Void, Void, Integer>{ 
    @Override 
    protected Integer doInBackground(Void... params) { 
      initProgress(); 
      return null; 
    } 
  } 
}


获取网页的例子:
import java.io.ByteArrayOutputStream; 
import java.io.InputStream; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import android.os.AsyncTask; 

//设置三种类型参数分别为String,Integer,String     
class PageTask extends AsyncTask<String, Integer, String> {     

        // 可变长的输入参数,与AsyncTask.exucute()对应     
        @Override     
        protected String doInBackground(String... params) {     
                try {     
                        HttpClient client = new DefaultHttpClient();     
                        // params[0] 代表连接的url     
                        HttpGet get = new HttpGet(params[0]);     
                        HttpResponse response = client.execute(get);     
                        HttpEntity entity = response.getEntity();     
                        long length = entity.getContentLength();     
                        InputStream is = entity.getContent();     
                        String s = null;     
                        if (is != null) {     
                                ByteArrayOutputStream baos = new ByteArrayOutputStream();     
                                byte[] buf = new byte[128];     
                                int ch = -1;     
                                int count = 0;     
                                while ((ch = is.read(buf)) != -1) {     
                                        baos.write(buf, 0, ch);     
                                        count += ch;     
                                        if (length > 0) {     
                                                // 如果知道响应的长度,调用publishProgress()更新进度     
                                                publishProgress((int) ((count / (float) length) * 100));     
                                        }     
                                        // 为了在模拟器中清楚地看到进度,让线程休眠100ms     
                                        Thread.sleep(100);     
                                }     
                                s = new String(baos.toByteArray());                        }     
                        // 返回结果     
                        return s;     
                } catch (Exception e) {     
                        e.printStackTrace();     
                }     
                return null;     
        }     

        @Override     
        protected void onCancelled() {     
                super.onCancelled();     
        }     
        @Override     
        protected void onPostExecute(String result) {     
                // 返回HTML页面的内容     
                message.setText(result);     
        }     
        @Override     
        protected void onPreExecute() {     
                // 任务启动,可以在这里显示一个对话框,这里简单处理     
                message.setText(R.string.task_started);     
        }     
        @Override     
        protected void onProgressUpdate(Integer... values) {     
                // 更新进度     
                message.setText(values[0]);     
        }     
}
分享到:
评论
1 楼 wxw404 2012-02-20  
引用
该task只能被执行一次,否则多次调用时将会出现异常

为什么会异常 这样的情况怎么处理,如果我需要多次调用呢

相关推荐

    Android AsyncTask用法和异步加载图片.rar

    总的来说,`AsyncTask`是Android中实现简单异步操作的有效工具,特别是对于轻量级的网络请求和计算任务。然而,对于更复杂的多线程需求,如大量的并发任务或复杂的任务协调,开发者可能需要考虑使用`IntentService`...

    Android的AsyncTask异步任务

    本篇文章将深入探讨Android的AsyncTask异步任务,以及如何在实践中应用。 首先,Android是一个基于事件驱动的系统,主线程(UI线程)负责处理用户交互,而复杂的计算或网络请求等耗时操作应在后台线程中执行,以免...

    android:AsyncTask实现异步处理任务.pdf

    AsyncTask是一个轻量级的异步任务框架,适用于执行与UI交互的短时间后台任务。它简化了线程管理和UI更新的过程,不需要直接处理线程和Handler。AsyncTask包含三个泛型类型: 1. `Params`:代表任务执行所需的输入...

    Android最全最简单的异步任务AsyncTask使用解析

    Android异步任务AsyncTask使用解析是指在Android应用程序中使用AsyncTask来实现异步任务的处理。AsyncTask是一个抽象类,使用时需要继承这个类,然后调用execute()方法。AsyncTask主要用来更新UI线程,比较耗时的...

    Android开发AsyncTask异步处理任务

    它的核心设计思想是简化多线程编程,将异步任务分为三个主要阶段:onPreExecute()、doInBackground()和onPostExecute()。 1. **onPreExecute()**: 这个方法在主线程中运行,通常用于初始化任务,例如显示进度...

    Android AsyncTask实现异步处理任务的方法详解

    "Android AsyncTask实现异步处理任务的方法详解" Android AsyncTask是Android操作系统提供的一个工具类,用于实现异步处理任务的方法详解。AsyncTask是抽象类,定义了三种泛型类型 Params,Progress和Result。...

    Android AsyncTask异步处理下载网页

    Android提供了一种便捷的机制,名为`AsyncTask`,用于在后台线程执行这些任务,同时允许在主线程更新UI。`AsyncTask`是一个轻量级的框架,设计用来简化在Android应用程序中进行后台操作的过程。 `AsyncTask`包含三...

    Android AsyncTask(异步) 简单样例

    AsyncTask是Android提供的一个类,它允许开发者在后台线程执行任务,然后在UI线程更新结果,以避免阻塞主线程导致应用无响应(ANR)的情况。它由三个泛型参数定义:Params(输入参数类型),Progress(后台执行过程...

    异步任务AsyncTask

    在Android开发中,异步任务(AsyncTask)是一种常见的处理耗时操作的方式,尤其是在主线程中需要执行网络请求、数据库操作或大型数据处理时。它能够避免UI线程被阻塞,提供更好的用户体验。让我们深入了解一下`...

    Android 使用AsyncTask异步更新UI界面

    `AsyncTask`是Android SDK提供的一种轻量级的异步任务处理类,它简化了在后台线程中执行任务并在UI线程中更新结果的过程。`AsyncTask`包含三个泛型参数:`Params`、`Progress`和`Result`,分别代表输入参数类型、...

    Android Handler AsyncTask 异步加载

    总的来说,理解并熟练掌握Handler和AsyncTask是Android开发的基础,它们能帮助开发者有效地处理异步任务,提高应用的性能和用户体验。在实际开发中,根据具体场景选择合适的方法,同时关注Android API的变化,适时...

    Android用AsyncTask异步加载图片(新)

    `AsyncTask`是Android提供的一种轻量级的多线程解决方案,它允许开发者在后台执行耗时操作,并在主线程中更新UI,避免了UI阻塞。本篇文章将深入探讨如何在Android中使用`AsyncTask`来异步加载网络图片。 首先,我们...

    Android 异步任务AsyncTask

    在Android应用开发中,异步任务(AsyncTask)是一个强大的工具,用于在后台线程执行耗时操作,然后在UI线程更新结果,避免了主线程(UI线程)因执行长时间运算而阻塞的问题。Android SDK提供的AsyncTask类使得开发者...

    Android AsyncTask 异步下载 提高篇

    `Params`表示异步任务执行前需要输入的参数类型,`Progress`表示后台任务执行过程中更新进度的类型,而`Result`则是后台任务完成后返回的结果类型。在下载图片的例子中,`Params`可能是图片的URL,`Result`可能是...

    android异步任务设计思详解(AsyncTask)

    Android中的异步任务设计主要体现在`AsyncTask`类上,它是Android SDK提供的一种方便快捷的多线程解决方案,用于在后台执行耗时操作,并在完成后更新UI。`AsyncTask`的广泛使用是因为它简化了线程与主线程之间的通信...

    Android studio异步数据加载ListView+Adapter+AsyncTask

    本教程将详细讲解如何在Android Studio中结合ListView、Adapter和AsyncTask实现异步数据加载。 首先,我们需要了解ListView的基本用法。ListView是一种可以滚动并显示多个同种类型的视图组件,通过Adapter进行数据...

    Android AsyncTask 源码解析

    通过以上对 AsyncTask 的源码解析和使用方法的介绍,你应该对如何在 Android 应用中高效地使用异步任务有了更深入的理解。在实际开发中,正确理解和使用 AsyncTask 可以帮助我们编写出更加流畅、响应快速的应用程序...

    安卓拍照上传录像监控录屏相关-android录音上传到服务器上传使用AsyncTask异步任务.rar

    在提供的资源中,"android录音上传到服务器,上传使用AsyncTask异步任务.rar" 提到了使用AsyncTask来处理这一问题。下面,我们将深入探讨Android系统中的这些功能及其与AsyncTask的结合使用。 1. **拍照上传**: ...

    Android中异步类AsyncTask用法总结

    总之,AsyncTask 是 Android 开发中处理短时、简单异步任务的得力助手,它简化了多线程与 UI 更新的同步问题,但不适用于所有异步场景。正确理解和使用 AsyncTask,可以帮助开发者更高效地构建用户界面,提升用户...

Global site tag (gtag.js) - Google Analytics