安卓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)。

相关推荐
2501_941982052 小时前
通过 API 实时监听企业微信外部群变更事件并同步本地数据库
android·自动化·企业微信·rpa
白雪落青衣3 小时前
buuoj course 1详细解析
android
恋猫de小郭3 小时前
Android 发布全新性能分析器,实用性和性能大升级
android·前端·flutter
Kapaseker3 小时前
为什么 Java 的数组需要 new 出来
android·java·kotlin
黄林晴4 小时前
颠覆开发!Google AI Studio 一句话生成原生 Android App
android·google io
恋猫de小郭4 小时前
Flutter 3.44 发布啦,超级大版本更新!!!
android·flutter·ios
zb200641204 小时前
Laravel10.x重磅升级:新特性全解析
android
2601_957418804 小时前
深入解析Android相机有线连接:PTP与MTP协议栈实现原理与实践
android·数码相机·智能手机
努力努力再努力wz4 小时前
【QT入门系列】QWidget 六大常用属性详解:windowOpacity、cursor、font、focus、toolTip 与 styleSheet
android·开发语言·数据结构·c++·qt·mysql·算法
撩得Android一次心动4 小时前
C语言基础笔记3【个人用】
android·c语言·开发语言·笔记