实例讲解Android中AsyncTask的使用详解

来源:互联网 发布:vb str是什么意思 编辑:程序博客网 时间:2024/06/15 16:07

——热爱开源,乐于分享

实例讲解Android中的AsyncTask的使用详解

一、单线程模型

在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程
2. 确保只在UI线程中访问Android UI工具包

二、为什么要使用AsyncTask?

基于单线程模型原则,我们需要将耗时操作放在UI线程以外,进行多线程处理,在Android中实现多线程任务机制有两种方式,Handler和AsyncTask。
1.Hnadler:
Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。
2.AsyncTask:
AsyncTask是android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。Android之所以提供AsyncTask这个类,就是为了方便我们在后台线程中执行操作,然后将结果发送给主线程,从而在主线程中进行UI更新等操作。在使用AsyncTask时,我们无需关注Thread和Handler,AsyncTask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可。

三、AsyncTask的5个回调方法及其之间的关系和作用

1.execute(Params… params):
启动执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute():
在execute(Params… params)被调用后立即执行,一般用来在执行后台任务前对UI做一些初始化操作。
3.doInBackground(Params… params):
在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress… values)来更新进度信息。
4.onProgressUpdate(Progress… values):
在调用publishProgress(Progress… values)时,此方法才会被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result):
当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,需注意
1.异步任务的实例对象(new AsyncTask)必须在UI线程中创建。
2.execute(Params… params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params… params)中更改UI组件的信息。

四、实例详解

下面使用一个简单例子详细说明AsyncTask的具体用法:
实现的功能:点击Button,实现网络图片下载)
(直接上代码,因为我已经在代码里面把注释写的非常清楚了)

1.先看一下工程结构:

这里写图片描述

2.activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.administrator.myasynctask.MainActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="image test"        android:onClick="loadImage"        tools:layout_editor_absoluteX="147dp"        tools:layout_editor_absoluteY="36dp" /></android.support.constraint.ConstraintLayout>

3.image.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:padding="16dp"    android:layout_height="match_parent">    <ImageView        android:id="@+id/img"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <ProgressBar        android:id="@+id/progressbar"        android:visibility="gone"        android:layout_centerInParent="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></RelativeLayout>

4.MainActivity.java

package com.example.administrator.myasynctask;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    //button的点击事件,在xml中写的onClick    public void loadImage(View view){        startActivity(new Intent(this,ImageTest.class));    }}

5.ImageTest.java

package com.example.administrator.myasynctask;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.View;import android.widget.ImageView;import android.widget.ProgressBar;import java.io.BufferedInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;/** * Created by Administrator on 2017/7/14. */public class ImageTest extends Activity {    private ImageView mImageView;//显示图片的ImageView    private ProgressBar mProgressBar;//圆形进度条,在XML中默认设置为隐藏的    private static String URL = "http://pic1.win4000.com/wallpaper/2/5603c62c082ca.jpg";    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.image);        mImageView= (ImageView) findViewById(R.id.img);        mProgressBar=(ProgressBar) findViewById(R.id.progressbar);        new MyAsyncTask().execute(URL);//启动异步线程时,所需要传递的参数,与AsyncTask<String, Void, Bitmap>定义的一致    }    //创建一个asynctask,继承自AsyncTask<String, Void, Bitmap>,用于连接网络,下载图片;    //三个参数分别是:传入的参数的类型(可变长度的参数)、后台任务执行的进度(一般用于条状progressbar,此处为圆形,不需要,故为void)、返回的结果的类型;    //在下面的几个重写方法中的参数与这三个参数是一致的、关联的;    class  MyAsyncTask extends AsyncTask<String, Void, Bitmap>{        //该方法在doInBackground之前执行,一般用于初始化操作        @Override        protected void onPreExecute() {            super.onPreExecute();            mProgressBar.setVisibility(View.VISIBLE);//显示进度条(默认是不显示的)        }        //该方法在doInBackground之后(即耗时操作完成)执行        @Override        protected void onPostExecute(Bitmap bitmap) {            super.onPostExecute(bitmap);            mProgressBar.setVisibility(View.GONE);//隐藏进度条            mImageView.setImageBitmap(bitmap);        }        //该方法执行耗时操作的具体实现        @Override        protected Bitmap doInBackground(String... params) {            //获取传递进来的参数            String url=params[0];            Bitmap bitmap=null;            URLConnection connection;            InputStream is;            try {                //从网络下载图片的方法!!!!!!!!                connection =new URL(url).openConnection();//打开网络连接对象                is=connection.getInputStream();//获取连接输入流                BufferedInputStream bis=new BufferedInputStream(is);//封装输入流                bitmap = BitmapFactory.decodeStream(bis);//利用工厂方法将输入流转换为bitmap                //关闭流                is.close();                bis.close();            } catch (IOException e) {                e.printStackTrace();            }            //返回bitmap,与第三个参数bitmap(result)一致            return bitmap;        }    }}

6.别忘了在AndroidManifest.xml文件中注册

<activity android:name=".ImageTest"/>

效果展示:

这里写图片描述
这里写图片描述

原创粉丝点击