异步任务-AsyncTask

本文详细介绍了Android中AsyncTask的工作原理及其应用场景,包括如何构建AsyncTask子类、使用回调方法等,并提供了异步加载图片及进度更新的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、主线程操作UI,耗时操作则在非主线程中执行

AsyncTask:子线程中更新UI;封装、简化异步操作

2、构建AsyncTask子类参数:

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

params:启动任务时候输入的参数类型

Progress:后台任务执行中返回进度值得类型

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

3、构建AsyncTask子类的回调方法:

通常指定如下的方法:

doInBackground:必须重写,异步执行后台线程将要完成的任务

onPreExecute:执行后台耗时操作前被调用,通常用户完成一些初始化操作

onPostExecute:当doInBackground()完成后,系统会自动调用,即:展示我们异步线程完成的结果

onProgressUpdate:在doInBackground()方法中调用publishProgress()方法更新任务的执行进度后,就会触发该方法

4、操作AsynckTask的简单实例

首先新建类MyAsyncTask异步加载类

package com.example.administrator.asynctaskdemo;

import android.os.AsyncTask;
import android.util.Log;

/**
 * 异步线程简单实例
 * 三参数:
 * @params 调用前传入参数
 * @progress 后台调用中返回值得类型
 * @result 后台执行完成后返回结果展示
 *四方法
 * doInBackground 必需有的执行方法
 * onPreExecute :执行后台调用之前的操作,通常完成一些数据的初始化
 * onPosExecute: 当doInBackground方法执行过后,系统自动调用,即展示异步线程完成的结果
 * onProgressUpDate: 当执行后台方法doInbackground()时调用publishProgress()更新任务的执行进度,会触发该方法
 */
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
    @Override
    protected Void doInBackground(Void... voids) {
        Log.i("AsyncTack","doInBackground");
        publishProgress();//如果这个方法里面有参数,将传递给onProgressUpdate()方法
        return null;
    }

    /**
     * 调用异步执行方法前的初始化方法
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.i("AsyncTack","onPreExecute");
    }

    /**
     * 异步完成后,系统自动调用展示异步线程结构
     * @param aVoid  异步线程执行完毕后,携带的需要传递的参数值
     */
    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Log.i("AsyncTask","onPostExecute");
    }

    /**
     *当doInBackground()方法执行中调用publishProgress()更新任务执行的进度后,通过onProgressUpdate()方法展示
     * @param values  publishProgress()传递过来需要跟新的任务执行进度
     */
    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        Log.i("AsyncTask","onProgressUpdate");
    }
}

在activity中实例化调用

//1、实例化异步方法
        MyAsyncTask myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute();//相当于线程中的.start

二、异步线程加载图片(获取网络数据流)

String url = params[0]//应为DoInBackground()方法后面跟的是不定长的数组,所以这里只需要取数组长度的第一位0即可
Bitmap bitmap = null;//接收类型初始化
URLConnection connection;//定义网络连接对象
InputStream is;//用于获取数据的输入流

try{
   connection = new URL(url).openConnection;//获取网络连接
   is=connection.getInputStream();//获取数据流
   BufferedInpuutStream bis = new BufferedInputStream(is);//包装获取的数据流
   Bitmap = BitmapFactory.decodeStream(bis);//将输入流解析成bitmap
   is.close();//关闭输入流
   bis.close();//关闭解析流
}catch (IOException e) {
               e.printStackTrace();
           }

这里有个问题不明白,为什么关闭获取输入流以后还要关闭BufferedInputStream包装数据流呢?一直想不明白

Thread.sleep(3000);//休眠3秒

doInBackground(String... strings)括号里面是不定长度的数据,这点需要注意

三、1、异步加载 模拟进度更新

class  MyAsyncTackProgress extends AsyncTask<Void ,Integer,Void>{
        @Override
        protected Void doInBackground(Void... voids) {
            //模拟进度更新
            for (int i=0;i<100;i++){
                publishProgress(i);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
        protected void onProgressUpdate(Integer...values){
            super.onProgressUpdate(values);
            //获取进度更新
        }
    }

三、2、因为异步加载方法调用底层线程池,但返回界面时,进程并未停止,所以需要在activity的生命周期的onPause方法中取消线程

    /**
     * another activity comes in front of the activity
     */
    @Override
    protected void onPause() {
        super.onPause();
          //对异步线程进行判断
        if (mTaskProgress != null &&mTaskProgress.getStatus()==AsyncTask.Status.RUNNING){
            //cancle只是将方法标记为取消状态,并不是真的取消了线程执行,需要调用isCancelled()
            mTaskProgress.cancel(true);
        }
    }

这里有一个需要注意,尤其是对新手来说,mTaskProgress.cancel(true),只要写这个方法了,就可以直接与isCancelled()是否等于true,

       protected Void doInBackground(Void... voids) {
            //模拟进度更新
            for (int i=0;i<100;i++){
                if (isCancelled()){
                    break;
                }
                publishProgress(i);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }


   protected void onProgressUpdate(Integer...values){
            super.onProgressUpdate(values);
            //获取进度更新
            if (isCancelled()) {
                return;
            }
        }

这里需要注意,doinbackgroud(),isCancelled()判断,直接用break;而onProgressUpdate()则是用的return;

四、参考代码demo,https://download.youkuaiyun.com/download/cryeye123/10562065

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值