AsyncTask介绍

AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
 

Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。

AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。

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

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。

使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:

  • doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

有必要的话你还得重写以下这三个方法,但不是必须的:

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

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

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

  下面举个例子:

  在main.xml文件中:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <ImageView
 7         android:id="@+id/imageView1"
 8         android:layout_width="wrap_content"
 9         android:layout_height="wrap_content"
10         android:layout_alignParentLeft="true"
11         android:layout_alignParentTop="true" />
12 
13     <Button
14         android:id="@+id/button1"
15         android:layout_width="wrap_content"
16         android:layout_height="wrap_content"
17         android:layout_alignParentBottom="true"
18         android:layout_alignParentLeft="true"
19         android:layout_alignParentRight="true"
20         android:text="从网上下载图片" />
21     
22 </RelativeLayout>

  在MainActivity.java文件中:

  1 package com.example.android_asynctask;
  2 
  3 
  4 
  5 import org.apache.http.HttpEntity;
  6 import org.apache.http.HttpResponse;
  7 import org.apache.http.client.HttpClient;
  8 import org.apache.http.client.methods.HttpGet;
  9 import org.apache.http.impl.client.DefaultHttpClient;
 10 import org.apache.http.util.EntityUtils;
 11 
 12 import android.os.AsyncTask;
 13 import android.os.Bundle;
 14 import android.app.Activity;
 15 import android.app.ProgressDialog;
 16 import android.graphics.Bitmap;
 17 import android.graphics.BitmapFactory;
 18 import android.util.Log;
 19 import android.view.Menu;
 20 import android.view.View;
 21 import android.view.View.OnClickListener;
 22 import android.widget.Button;
 23 import android.widget.ImageView;
 24 import android.widget.Toast;
 25 
 26 public class MainActivity extends Activity {
 27 
 28     private ProgressDialog dialog;
 29     private ImageView imageView ;
 30     private Button button;
 31     @Override
 32     protected void onCreate(Bundle savedInstanceState) {
 33         super.onCreate(savedInstanceState);
 34         setContentView(R.layout.activity_main);
 35         imageView = (ImageView) findViewById(R.id.imageView1);
 36         button = (Button) findViewById(R.id.button1);
 37         button.setOnClickListener(new OnClickListener() {
 38             
 39             @Override
 40             public void onClick(View v) {
 41                 // TODO 自动生成的方法存根
 42                 //执行异步任务的操作
 43                 new MyTask().execute("http://p0.so.qhimg.com/t01aa653c8cd80777a5.jpg");
 44             }
 45         });
 46         dialog = new ProgressDialog(this);
 47         dialog.setTitle("提示信息");
 48         dialog.setMessage("正在下载,请稍候...");
 49     }
 50 
 51     @Override
 52     public boolean onCreateOptionsMenu(Menu menu) {
 53         // Inflate the menu; this adds items to the action bar if it is present.
 54         getMenuInflater().inflate(R.menu.main, menu);
 55         return true;
 56     }
 57 
 58     /**
 59      * 使用异步任务的规则
 60      * 1,声明一个继承AsyncTask 标注三个参数
 61      * 2,第一个参数通常表示的是访问网络的路径,第二个参数表示进度的刻度
 62      *       第三个参数表示任务执行的返回结果
 63      * @author xielianwu
 64      *
 65      */
 66     public  class MyTask extends AsyncTask<String, Void, Bitmap>{
 67 
 68         //主要完成耗时操作
 69         @Override
 70         protected Bitmap doInBackground(String... params) {
 71             // TODO 自动生成的方法存根
 72             //使用网络连接类HttpClient完成对网络数据的提取
 73             HttpClient client = new DefaultHttpClient();
 74             HttpGet get = new HttpGet(params[0]);
 75             Bitmap bitmap = null;
 76             int i = 1;
 77             try {
 78                 
 79                 Log.i("test","test");
 80                 HttpResponse response = client.execute(get);
 81                 if(response.getStatusLine().getStatusCode() == 200){
 82                     HttpEntity entity = response.getEntity();
 83                     byte[] data = EntityUtils.toByteArray(entity);
 84                     bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
 85                     if(bitmap == null)
 86                         i = 0;
 87                     Toast.makeText(MainActivity.this,bitmap.toString() +"i=" +i, 1).show();
 88                     Log.i("bitmap", bitmap.toString() +"i=" +i);
 89                 }
 90             } catch (Exception e) {
 91                 // TODO: handle exception
 92                 e.printStackTrace();
 93             }
 94             return bitmap;
 95         }
 96 
 97         //任务执行之前操作
 98         @Override
 99         protected void onPreExecute() {
100             // TODO 自动生成的方法存根
101             super.onPreExecute();
102             dialog.show();
103         }
104 
105         //主要更新UI
106         @Override
107         protected void onPostExecute(Bitmap result) {
108             // TODO 自动生成的方法存根
109             super.onPostExecute(result);
110             imageView.setImageBitmap(result);
111             dialog.dismiss();
112         
113         }
114     }
115     
116 }

注意在AndroidManifest.xml配置文件中配置网络权限:

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

运行结果:

 

原文地址:https://www.cnblogs.com/SoulCode/p/5468245.html