志不强者智不达,言不信者行不果。这篇文章主要讲述Android异步任务AsyncTask相关的知识,希望能为你提供帮助。
为什么要使用异步任务?
我们知道安卓中更新UI组件必须在UI线程(主线程)中进行更新,为了避免UI线程被阻塞而失去响应,android一般建议将耗时的操作放在新线程中完成,但是新线程也可能需要动态更新UI组件,比如需要从网上下载一张图片然后在ImageView中显示出来,这时就应该将链接网络,获取网络数据的操作放在新线程中完成:问题是在获取网络资源之后新线程不了允许直接更新UI组件,这个时候就需要用到异步处理了。
异步处理除了使用Handler类传递消息处理之外还有一种更加轻量级的处理方式AsycnTask,适用于简单的异步处理,不需要借助线程和Handler就可以实现
AsycnTask类基本介绍:
AsycnTask<
Params,Progress,Result>
是一个抽象类,通常用于被继承,继承这个类需要指定如下的三个泛型参数
Params:启动任务执行的输入参数类型
Progress:后台任务完成的进度值类型
【Android异步任务AsyncTask】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" 2android:layout_width="match_parent" 3android:layout_height="match_parent" 4android:orientation="vertical"> 5 6 7< Button 8 9android:layout_width="match_parent" 10android:layout_height="wrap_content" 11android:onClick="btn" 12android:text="提交" /> 13 14 15< ProgressBar 16android:id="@+id/bar" 17android:layout_width="match_parent" 18android:layout_height="wrap_content" 19android:padding="20px" 20android:visibility="gone" /> 21 22< ImageView 23android:id="@+id/ima" 24android:layout_width="wrap_content" 25android: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 22ProgressBar bar; 23String url = new String("https://timgsa.baidu.com/timg?image& quality=80& size=b9999_10000& sec=1514633107382& di=6811991b77bb94183ecfc91296644c53& imgtype=0& src=https://www.songbingjia.com/android/http%3A%2F%2Fimage.tianjimedia.com%2FuploadImages%2F2014%2F289%2F01%2FIGS09651F94M.jpg"); 24ImageView ima; 25 26 27@Override 28protected void onCreate(Bundle savedInstanceState) { 29super.onCreate(savedInstanceState); 30setContentView(R.layout.activity_main); 31ima = (ImageView) findViewById(R.id.ima); 32bar = (ProgressBar) findViewById(R.id.bar); 33 34 35} 36 37public void btn(View view) { 38new MyAsyncTask().execute(url); //execute方法必须在UI线程中调用 39} 40 41 //自定义内部类继承AsuncTask 42class MyAsyncTask extends AsyncTask< String, Void, Bitmap> { 43 44@Override//在doInBackground()方法前执行 45protected void onPreExecute() { 46super.onPreExecute(); 47bar.setVisibility(View.VISIBLE); //设置进度条可见 48} 49 50@Override 51protected Bitmap doInBackground(String... strings) { 52Bitmap bitmap = null; 53try { 54Thread.sleep(3000); 55 //获取传进来的URL值 56String url = strings[0]; 57try { 58URLConnection urlConnection = new URL(url).openConnection(); 59InputStream inputStream = urlConnection.getInputStream(); 60 //通过decodeStream解析输入流 61bitmap = BitmapFactory.decodeStream(inputStream); 62 63 64} catch (IOException e) { 65e.printStackTrace(); 66} 67 68 69} catch (InterruptedException e) { 70e.printStackTrace(); 71} 72 73 74return bitmap; 75 76} 77 78 79@Override 80protected void onPostExecute(Bitmap bitmap) { 81super.onPostExecute(bitmap); 82bar.setVisibility(View.GONE); //设置进度条不可见 83ima.setImageBitmap(bitmap); //把从网上获取到的图片资源设置到ImageView中 84} 85} 86 87 }
推荐阅读
- 关于在 App Store 中将 APP 下的公司名称改成英文或者中文的相关流程
- android sdk manager更新地址
- Unity(Android版)和Android原生APP简单实现版本更新
- SpringBoot Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFact
- 解决找不到mapper.xml文件的问题
- Android 异步加载神器Loader全解析
- gradle-4.1-all.zip离线包下载 极速 android studio2.3 3.0编译必备
- Android运用Builder来创建Alertdialog
- jdk的设置及安装android studio提示does not point to a valid jvm问题