Android异步任务AsyncTask

Posted 西红柿里没有番茄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android异步任务AsyncTask相关的知识,希望对你有一定的参考价值。

  为什么要使用异步任务?

我们知道安卓中更新UI组件必须在UI线程(主线程)中进行更新,为了避免UI线程被阻塞而失去响应,android一般建议将耗时的操作放在新线程中完成,但是新线程也可能需要动态更新UI组件,比如需要从网上下载一张图片然后在ImageView中显示出来,这时就应该将链接网络,获取网络数据的操作放在新线程中完成:问题是在获取网络资源之后新线程不了允许直接更新UI组件,这个时候就需要用到异步处理了。

 

  异步处理除了使用Handler类传递消息处理之外还有一种更加轻量级的处理方式AsycnTask,适用于简单的异步处理,不需要借助线程和Handler就可以实现

 

  AsycnTask类基本介绍:

  AsycnTask<Params,Progress,Result>是一个抽象类,通常用于被继承,继承这个类需要指定如下的三个泛型参数

  Params:启动任务执行的输入参数类型

  Progress:后台任务完成的进度值类型

  Result:后台执行任务完成返回的结果类型

 

  AsycnTask的方法介绍:

  doInBackground(Params...param):使用AsycnTask必须重写这个方法,重写这个方法就是放后台线程要完成的任务。在这个方法中可以调用publishProgress(Progress..values)方法更新任务的执行进度

  onPreExecute():这个方法会在执行后台耗时操作前被系统调用,也就是会在doInBackground(Params...param)方法前执行,一般在这个方法中完成一些初始化操作,比如让原本隐藏的进度条显示出来

  onPostExecute(Result result):当执行完doInBackground(Params...param)方法时系统会自动调用这个方法,并且doInBackground方法返回的值会传递给这个方法

  onProgressUpdate():在doInBackground(Params...param)方法中调用publishProgress(Progress..values)方法更新任务进度后会自动调用这个方法

  execute():有AsycnTask的子类的实例对象调用,用于启动耗时任务

 

 

   注意点:

  •   AsycnTask的doInBackground(Params...param)、onPreExecute()、onPostExecute(Result result)、onProgressUpdate()四个方法不可以自己手动调用,这四个方法是在调用execute()方法之后由系统自动调用的。
  • 执行UI更新的操作不能在doInBackground(Params...param)方法中进行,可以在onPreExecute()、onPostExecute(Result result)、onProgressUpdate()三个方法中任一一个方法中进行,但是要区别出这几个方法执行的先后顺序,否则就算执行了UI组件更行也可能因为在耗时操作之前执行而没有任何效果。
  • 必须在UI线程中创建AsycnTask的实例
  • 使用AsycnTask的实例调用execute()方法时必须在UI线程中

 

  以下源代码的功能介绍:通过网上图片的地址调用将图片显示在APP中的ImageView中,当图片还没加载出来前显示进度条,图片加载出来之后隐藏进度条  

 

Activity_main.xml布局文件:

 

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical">
 5 
 6 
 7     <Button
 8 
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:onClick="btn"
12         android:text="提交" />
13 
14 
15     <ProgressBar
16         android:id="@+id/bar"
17         android:layout_width="match_parent"
18         android:layout_height="wrap_content"
19         android:padding="20px"
20         android:visibility="gone" />
21 
22     <ImageView
23         android:id="@+id/ima"
24         android:layout_width="wrap_content"
25         android:layout_height="wrap_content" />
26 
27 
28 </LinearLayout>

 

 

 

Activity_main.java源代码:

 1 package com.contentprovide.liuliu.asynctaskdemo;
 2 
 3 import android.graphics.Bitmap;
 4 import android.graphics.BitmapFactory;
 5 import android.os.AsyncTask;
 6 import android.support.v7.app.AppCompatActivity;
 7 import android.os.Bundle;
 8 import android.view.View;
 9 import android.widget.Button;
10 import android.widget.ImageView;
11 import android.widget.ProgressBar;
12 
13 import java.io.BufferedInputStream;
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.net.URL;
18 import java.net.URLConnection;
19 
20 public class MainActivity extends AppCompatActivity {
21 
22     ProgressBar bar;
23     String url = new String("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1514633107382&di=6811991b77bb94183ecfc91296644c53&imgtype=0&src=http%3A%2F%2Fimage.tianjimedia.com%2FuploadImages%2F2014%2F289%2F01%2FIGS09651F94M.jpg");
24     ImageView ima;
25 
26 
27     @Override
28     protected void onCreate(Bundle savedInstanceState) {
29         super.onCreate(savedInstanceState);
30         setContentView(R.layout.activity_main);
31         ima = (ImageView) findViewById(R.id.ima);
32         bar = (ProgressBar) findViewById(R.id.bar);
33 
34 
35     }
36 
37     public void btn(View view) {
38         new MyAsyncTask().execute(url);//execute方法必须在UI线程中调用
39     }
40 
41 //    自定义内部类继承AsuncTask
42     class MyAsyncTask extends AsyncTask<String, Void, Bitmap> {
43 
44         @Override//在doInBackground()方法前执行
45         protected void onPreExecute() {
46             super.onPreExecute();
47             bar.setVisibility(View.VISIBLE);//设置进度条可见
48         }
49 
50         @Override
51         protected Bitmap doInBackground(String... strings) {
52             Bitmap bitmap = null;
53             try {
54                 Thread.sleep(3000);
55 //               获取传进来的URL值
56                 String url = strings[0];
57                 try {
58                     URLConnection urlConnection = new URL(url).openConnection();
59                     InputStream inputStream = urlConnection.getInputStream();
60 //                  通过decodeStream解析输入流
61                     bitmap = BitmapFactory.decodeStream(inputStream);
62 
63 
64                 } catch (IOException e) {
65                     e.printStackTrace();
66                 }
67 
68 
69             } catch (InterruptedException e) {
70                 e.printStackTrace();
71             }
72 
73 
74             return bitmap;
75 
76         }
77 
78 
79         @Override
80         protected void onPostExecute(Bitmap bitmap) {
81             super.onPostExecute(bitmap);
82             bar.setVisibility(View.GONE);//设置进度条不可见
83             ima.setImageBitmap(bitmap);//把从网上获取到的图片资源设置到ImageView中
84         }
85     }
86 
87 }

 

 

 

 

 

 

 

 

 

 

以上是关于Android异步任务AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章

Android 我应该在异步任务中将片段作为弱引用传递吗?

Android源代码解析之--&gt;异步任务AsyncTask

android中AsyncTask中的ProgressDialog

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

android:异步任务asyncTask介绍及异步任务下载图片(带进度条)

android源码解析之-->异步任务AsyncTask