详解Android App中的AsyncTask异步任务执行方式

基本概念

AsyncTask:异步任务,从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作。AsyncTask允许我们的执行一个异步的任务在后台。我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件。通过AsyncTask我们可以轻松的解决多线程之间的通信问题。

怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我们如果要定义一个AsyncTask,就需要定义一个类来继承AsyncTask这个抽象类,并实现其唯一的一个 doInBackgroud 抽象方法。要掌握AsyncTask,我们就必须要一个概念,总结起来就是: 3个泛型,4个步骤。

3个泛型指的是什么呢?我们来看看AsyncTask这个抽象类的定义,当我们定义一个类来继承AsyncTask这个类的时候,我们需要为其指定3个泛型参数:

AsyncTask <Params, Progress, Result>

  • Params: 这个泛型指定的是我们传递给异步任务执行时的参数的类型
  • Progress: 这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
  • Result: 这个泛型指定的异步任务执行完后返回给UI线程的结果的类型

我们在定义一个类继承AsyncTask类的时候,必须要指定好这三个泛型的类型,如果都不指定的话,则都将其写成Void,例如:

AsyncTask <Void, Void, Void>
4个步骤:当我们执行一个异步任务的时候,其需要按照下面的4个步骤分别执行

  • onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog
  • doInBackground(Params... params): 在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作
  • onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新
  • onPostExecute(Result... result): 当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上

为什么我们的AsyncTask抽象类只有一个 doInBackground 的抽象方法呢??原因是,我们如果要做一个异步任务,我们必须要为其开辟一个新的Thread,让其完成一些操作,而在完成这个异步任务时,我可能并不需要弹出要给ProgressDialog,我并不需要随时更新我的ProgressDialog的进度条,我也并不需要将结果更新给我们的UI界面,所以除了doInBackground 方法之外的三个方法,都不是必须有的,因此我们必须要实现的方法是 doInBackground 方法。

 实例
下面实现一个打开网络图片的demo:

package com.app.main;

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 org.apache.http.util.EntityUtils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Main extends Activity {

  String url = "http://e.hiphotos.baidu.com/image/w%3D2048/sign=61711bd121a446237ecaa262ac1a730e/e850352ac65c10385f10af69b3119313b07e892a.jpg";
  ImageView imgView = null;
  Button btn = null;
  ProgressDialog dialog = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    imgView = (ImageView) this.findViewById(R.id.imageview);
    btn = (Button) this.findViewById(R.id.btn);
    dialog = new ProgressDialog(this);
    dialog.setMessage("下载图片中......");

    btn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View view) {

        new MyTask().execute(url);
      }

    });

  }

  class MyTask extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected void onPreExecute() {

      super.onPreExecute();

      dialog.show();

    }

    @Override
    protected Bitmap doInBackground(String... params) {

      Bitmap bitmap = null;

      String url = params[0];

      HttpClient client = new DefaultHttpClient();

      HttpGet getMethod = new HttpGet(url);

      try {

        HttpResponse response = client.execute(getMethod);

        if (response.getStatusLine().getStatusCode() == 200) {
          HttpEntity entity = response.getEntity();

          byte[] data = EntityUtils.toByteArray(entity);

          bitmap = BitmapFactory
              .decodeByteArray(data, 0, data.length);

        }

      } catch (Exception e) {

      }

      return bitmap;
    }

    @SuppressLint("NewApi")
    @Override
    protected void onPostExecute(Bitmap result) {

      super.onPostExecute(result);

      imgView.setImageBitmap(result);

      dialog.dismiss();
    }

  }

}

实现的效果如图:

(0)

相关推荐

  • 详解Android中AsyncTask机制

    在Android当中,提供了两种方式来解决线程直接的通信问题,一种是通过Handler的机制,还有一种就是今天要详细讲解的 AsyncTask 机制. AsyncTask       AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程. 怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线

  • Android的异步任务AsyncTask详解

    AsyncTask,顾名思义,异步任务.说到异步,最简单的理解就是不同步.再复杂一点理解,就得举例子了. 假设我要去火车站买票,刚到火车站我突然发现我忘了带身份证.怎么办?怎么办! 想办法,想办法!我想我应该找个在学校的同学帮我送过来,因为我不能自己回去拿啊,还要排队呢,走不开.嗯,要找人送过来.但是问题来了,我找人送身份证了,我去排队了,如果排到第一位了身份证还没到怎么办?叮,脑袋上面突然亮了一个小灯泡,机智的我在排队前想到了两种方案: 第一种方案,让售票员等着我,我后面队伍里买票的人也等着我

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

    Android AsyncTask实现异步处理任务的方法详解 在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. Android 单线程模型概念详解:http://www.jb51.net/article/112165.htm 在单线程模型中始终要记住两条法则: 不要阻塞UI线程 确保只在UI线程中访问Android UI工具包 当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),

  • Android中使用AsyncTask实现文件下载以及进度更新提示

    Android提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单.相对Handler来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handter即可实现.AsyncTask是抽象类.AsyncTask定义了三种泛型类型Params,Progress和Result: Params启动任务执行的输入参数,比如,HTTP请求的URL. Progress后台任务执行的百分比. Result后台执行任务最终返回的结果,比如String.

  • Android AsyncTask完全解析 带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制. 不过为了更加方便我们在子线程中更新UI元素,Android从1.5版本就引入了一个AsyncTask类,使用它就可以非常灵活方便地从子线程切换到UI线程,我们本篇文章的主角也就正是它了. AsyncTask很早就出现在Android的API里了,所以我相信大多数朋友对它的用法都已经非常熟悉.不过今天我

  • Android开发笔记之:深入理解多线程AsyncTask

    Understanding AsyncTaskAsyncTask是Android 1.5 Cubake加入的用于实现异步操作的一个类,在此之前只能用Java SE库中的Thread来实现多线程异步,AsyncTask是Android平台自己的异步工具,融入了Android平台的特性,让异步操作更加的安全,方便和实用.实质上它也是对Java SE库中Thread的一个封装,加上了平台相关的特性,所以对于所有的多线程异步都强烈推荐使用AsyncTask,因为它考虑,也融入了Android平台的特性,

  • Android中AsyncTask的用法实例分享

    *  AsyncTask 看上去修改后的connect()方法已经可用了,但是这种匿名线程的方式是存在缺陷的:第一,线程的开销较大,如果每个任务都要创建一个线程,那么应用 程序的效率要低很多:第二,线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负. 另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿. 为了解决这一问题,OPhone在1.5版本引入了AsyncTask.AsyncTask的特

  • Android中通过AsyncTask类来制作炫酷进度条的实例教程

    AsyncTask (API level 3,所以几乎所有目前在市面上流通的 Android 版本皆可使用) 是除 Thread 外的另一种选择,Android 团队鼓励主执行绪(UI thread) 专注于操作 & 画面的流畅呈现, 其余工作 (如网络资料传输.档案/磁碟/资料存取) 最好都在背景执行: Thread 通常要搭配 Handler 使用,而 AsyncTask 用意在简化背景执行 thread 程序码的撰写. 如果您预期要执行的工作能在几秒内完成,就可以选择使用 AsyncTas

  • 详解Android App中的AsyncTask异步任务执行方式

    基本概念 AsyncTask:异步任务,从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作.AsyncTask允许我们的执行一个异步的任务在后台.我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件.通过AsyncTask我们可以轻松的解决多线程之间的通信问题. 怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我

  • 详解Android App中创建ViewPager组件的方法

    现在很多app一打开就是一个ViewPager,然后可以用手指滑,每滑一次就换一张图,底下还会有圈圈表示说现在滑到第几章~ 通常这些图片都是放功能简介或是使用教学之类的,我的需求很简单,就是上面提到的那样而已. 有两种做法,一种是找现有套件,查了一堆资料每个都跟我推荐ViewPagerIndicator这套,我之前也看过这套,只是看起来需要有fragment再加上google play范例好像载不到了,所以只好自己实做一个. Viewpager的实作可参考Android ViewPager使用详

  • 详解Android App中使用VideoView来实现视频播放的方法

    通过VideoView播放视频的步骤: 1.在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件 2.调用VideoView的如下两个方法来加载指定的视频 (1)setVidePath(String path):加载path文件代表的视频 (2)setVideoURI(Uri uri):加载uri所对应的视频 3.调用VideoView的start().stop().psuse()方法来控制视频的播放 VideoView通过与MediaController类结合使用,

  • 详解Android App中ViewPager使用PagerAdapter的方法

    PageAdapter是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即可使用. 要使用PagerAdapter, 首先要继承PagerAdapter类,至少覆盖以下方法: 在每次创建ViewPager或滑动过程中,以下四个方法都会被调用,而instantiateItem和destroyItem中的方法要自己去实现. public abstract int getCount(); 这个方法,是获取当前窗体界面数 public a

  • 详解Android Libgdx中ScrollPane和Actor事件冲突问题的解决办法

    详解Android Libgdx中ScrollPane和Actor事件冲突问题的解决办法 在Libgdx的使用过程中,经常会用到ScrollPane这个widget,来实现滑动效果, 如下所示: 但是如果想在上面的效果上添加一点扩展,比如ScrollPane中的Actor可以从ScrollPane中移出来,并添加到Stage中,则需要添加额外的逻辑 具体代码参考如下: /** * Created by Danny.姜 on 17/7/26. */ public class TestAdapter

  • 详解Spring Security 中的四种权限控制方式

    Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Security 提供的方式做授权,也可以自定义授权逻辑.一句话,你想怎么玩都可以! 今天松哥来和大家介绍一下 Spring Security 中四种常见的权限控制方式. 表达式控制 URL 路径权限 表达式控制方法权限 使用过滤注解 动态权限 四种方式,我们分别来看.  1.表达式控制 URL 路径权

  • 详解Android TableLayout中stretchColumns、shrinkColumns的用法

    详解Android 中TableLayout中stretchColumns.shrinkColumns的用法 android:stretchColumns="1" android:shrinkColumns="1"这两个属性是TableLayout所特有的,也是这两个属性影响了子对象的布局. 表格布局是按照行列来组织子视图的布局.表格布局包含一系列的Tabrow对象,用于定义行(也可以使用其它子对象).表格布局不为它的行.列和单元格显示表格线.每个行可以包含个以上(

  • 详解Android Studio中Git的配置及协同开发

    一. Android Stutio配置git setting–>Version Control–>Git–>Path to Git executable中选择git.exe的位置,这个Stutio一般会默认配置好: 配置完路径后点击后面的Test按钮,出现下面提示框则表示配置成功: 二. 将项目分享到github 1. 设置github账号密码 打开Setting–>Version Control–>GitHub,填写完账号密码后,点击Test测试,如果连接成功会弹出如下提示

  • Android App中实现图片异步加载的实例分享

    一.概述 一般大量图片的加载,比如GridView实现手机的相册功能,一般会用到LruCache,线程池,任务队列等:那么异步消息处理可以用哪呢? 1.用于UI线程当Bitmap加载完成后更新ImageView 2.在图片加载类初始化时,我们会在一个子线程中维护一个Loop实例,当然子线程中也就有了MessageQueue,Looper会一直在那loop停着等待消息的到达,当有消息到达时,从任务队列按照队列调度的方式(FIFO,LIFO等),取出一个任务放入线程池中进行处理. 简易的一个流程:当

  • 详解Android Activity中的几种监听器和实现方式

    Activity 在Activity中,使用findViewById(int resId)方法与布局中的控件绑定 View常用事件接口 View的事件监听是指用户与应用交互,当用户对View进行点击.长按.触摸.移动等动作时.程序对这些动作进行处理 OnClickListener    点击View时的监听 OnLongClickListener  长按View时的监听 OnTouchListener   触摸View时的监听 1.android系统中,OnClickListener 是一种处理

随机推荐