安卓AsyncTask使用

目录

  • 一、简介
    • [1.1 AsyncTask 参数简介](#1.1 AsyncTask 参数简介)
    • [1.2 常用方法](#1.2 常用方法)
    • [1.3 执行顺序](#1.3 执行顺序)
    • [1.4 使用注意](#1.4 使用注意)
    • [1.5 使用步骤](#1.5 使用步骤)
  • 二、使用示例
  • 三、应用场景

一、简介

java 复制代码
public abstract class AsyncTask<Params, Progress, Result> {

1.1 AsyncTask 参数简介

  • Params:开始异步任务执行时传入的参数类型,对应excute()中传递的参数
  • Progress:异步任务执行过程中,返回下载进度值的类型,对应publishProgress()中的参数
  • Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致

1.2 常用方法

方法 描述 备注
execute() 触发执行异步线程,手动调用 必须执行在UI线程
onPreExecute() 在 doInBackground() 执行前先执行的方法 主线程 中执行 , 可更新 UI 界面 ;
doInBackground() 核心方法 , 执行异步任务 , 该方法在 子线程 中执行 不能更改UI,可调用publishProgress()更新进度信息
publishProgress() 常用于doInBackground()方法中用来更新进度信息
onProgressUpdate() 调用 publishProgress() 回调的方法 主线程 中执行 , 可更新 UI 界面 ;
onPostExecute() doInBackground() 执行完毕后再执行的方法 主线程 中执行 , 可更新 UI 界面 ;
onCancelled() 将异步任务设置为:取消状态,异步任务被取消时自动调用 该方法被调用时,onPostExecute()就不会被调用

1.3 执行顺序

1.4 使用注意

  • UI 线程创建
  • UI 线程调用执行 execute():创建后只能执行一次
  • AsyncTask不与任何组件绑定生命周期
    在Activity 或 Fragment中使用 AsyncTask时,最好在Activity 或 Fragment的onDestory()调用 cancel(boolean);
  • 建议AsyncTask应被声明为Activity的静态内部类
    若AsyncTask被声明为Activity的非静态内部类,当Activity需销毁时,会因AsyncTask保留对Activity的引用 而导致Activity无法被回收,最终引起内存泄露
  • 在Activity恢复时的对应方法 重启 任务线程
    当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()将不生效,即无法更新UI操作

1.5 使用步骤

创建 AsyncTask 子类 & 根据需求实现核心方法

创建 AsyncTask子类的实例对象(即 任务实例)

手动调用execute()从而执行异步线程任务


二、使用示例

使用ProgressBar显示任务加载进度:

MyAsyncTask

java 复制代码
public class MyAsyncTask extends AsyncTask<Integer, Integer, String> {

    private TextView textView;
    private ProgressBar progressBar;

    public MyAsyncTask(TextView textView, ProgressBar progressBar) {
        super();
        this.textView = textView;
        this.progressBar = progressBar;
    }

    //最先执行的方法
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        textView.setText("加载完成!");
    }

    /**
     * 在doInBackground方法中每次调用publishProgress方法都会触发此方法
     * 此方法运行在ui线程中,可操作ui控件
     *
     * @param values
     */
    @Override
    protected void onProgressUpdate(final Integer... values) {
        super.onProgressUpdate(values);
        progressBar.setProgress(values[0]);
        //setText的参数是string,不然报错
        textView.setText("loading..." + values[0] + "%");
    }

    //后台执行的方法
    @Override
    protected String doInBackground(Integer... integers) {
        int i = 0;
        for (i = 10; i <= 100; i += 10) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            publishProgress(i);
        }
        Log.d("henry", String.valueOf(integers[0]));
        return i + integers[0].intValue() + "";
    }
}

布局文件:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp" />

    <TextView
        android:id="@+id/tv_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=" 0 / 100" />

    <Button
        android:id="@+id/b9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100dp"
        android:text="start" />

</LinearLayout>

activity

java 复制代码
public class AsyncTaskActivity extends AppCompatActivity {
    private ProgressBar progressBar;
    private TextView tv;
    private Button b9;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
        progressBar = findViewById(R.id.progressBar);
        tv = findViewById(R.id.tv_num);
        b9 = findViewById(R.id.b9);
        b9.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyAsyncTask myAsyncTask = new MyAsyncTask(tv, progressBar);
                myAsyncTask.execute(100);
            }
        });
    }
}

显示如下:

三、应用场景

AsyncTask 是 Android 中用于在后台线程执行异步任务的类,常用于在后台执行耗时操作,如网络请求、数据库操作等,然后将结果返回到主线程更新 UI。

应用场景:

  • 网络请求:在后台线程中执行网络请求操作,获取数据后更新 UI。
  • 数据库操作:在后台线程中执行数据库的增删改查操作。
  • 图片加载:在后台线程中加载大图或多张图片,避免卡顿。
  • 其他耗时操作:如文件读写、计算操作等。

优点:

简单易用:AsyncTask 封装了后台线程和主线程之间的通信,使用方便。

更新 UI:可以在后台线程执行耗时操作后更新 UI,避免主线程阻塞。

可以取消任务:可以在任何时候取消 AsyncTask 的执行,避免资源浪费。

缺点:

生命周期管理:AsyncTask 的生命周期与 Activity 或 Fragment 绑定,容易出现内存泄漏。

并发性能:AsyncTask 默认是串行执行的,如果需要并发执行多个任务,则需要手动管理。

不适合长时间任务:AsyncTask 适合执行短时间的任务,长时间任务可能会导致 ANR(Application Not Responding)。

相关推荐
雨白5 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空8 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭8 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日9 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安9 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑10 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟14 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体