AsyncTask详解及简单示例

总体概述

众所周知,程序的执行主要是在UI线程上执行(也就是主线程),当有耗时任务的时候,例如从网络上下载文件、进行数据库查询、进行复杂的逻辑运算的时候,如果在主线程中执行,会导致主线程阻塞,APP无法响应,asynctask是Android官方提供的帮助类,可以开启个独立线程执行某个耗时任务。

使用方法

AsyncTask是一个抽象类,如果使用必须用别的类来继承他。主要的方法如下:

方法作用线程
onPreExecute()程序执行前设置UI主线程
doInBackground()在后台执行的具体任务子线程
onProgressUpdate()程序执行过程中设置UI主线程
onPostExecute()程序执行完设置UI主线程

在这里插入图片描述

AsyncTask <Params, Progress, Result>
参数名称参数作用
ParamsdoInBackground()参数
ProgressonProgressUpdated()参数
ResultonPostExecute()参数

注意:
不需要写参数就写void
doInBackground必须实现,其他方法可以不实现
onPostExecute使用的参数是doInBackground的返回值
doInBackground参数需要在构造AsyncTask时传入

一个简单的例子

点击按钮,文字变为Waiting,并且随机等待一段时间后,更新文字内容。
(随机等待一段时间模拟费时操作)

效果

在这里插入图片描述

项目结构

在这里插入图片描述

activity_main.xml代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    android:layout_margin="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I am ready to start work!"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:onClick="startTask"
        android:text="Start Task"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

代码很好懂,Button绑定个事件,在MainActivity中进行实现。

MainActivity代码

public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //找到控件
        mTextView = this.findViewById(R.id.textView1);
    }

    public void startTask(View view) {
        mTextView.setText("Wait.......");
        //开始AsyncTask
        new SimpleAsyncTask(mTextView).execute();
    }
}

其他代码都很好懂,重点说一下这个:

new SimpleAsyncTask(mTextView).execute();

mTextView为什么传入,其实就是SimpleAsyncTask这个的构造函数所需要的参数,之后的execute就表示开始执行,因为onPreExecute不需要参数,所以这里不传入,根据情况传参。

SimpleAsyncTask代码

public class SimpleAsyncTask extends AsyncTask<Void, Integer, String> {
    private WeakReference<TextView> mTextView;

    SimpleAsyncTask(TextView tv) {
        //弱引用  可以被垃圾回收机制回收如果必要的话
        mTextView = new WeakReference<>(tv);
    }
    
    @Override
    protected String doInBackground(Void... voids) {
        Random r = new Random();
        int n = r.nextInt(11);
        int s = n * 200;
        try {
            Thread.sleep(s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "Awake at last after sleeping for " + s + " milliseconds!";
    }

    @Override
    protected void onPostExecute(String s) {
        // 参数String是doInBackground返回的参数
        // 因为是弱引用  必须用get方法获得具体的对象
        mTextView.get().setText(s);
    }
}

首先讲一下弱引用
假如是普通的方法,当Activity被摧毁之后,对TextView的引用意味着Activity永远不会被垃圾回收机制回收,个人理解,因为你要用这个Activity,所以其不会被回收,会导致内存泄漏;弱引用,代表必要情况下可以被垃圾回收机制回收。

doInBackground–必须实现的方法
该代码中随机暂停一段时间后,返回字符串。

onPostExecute–在doInBackground执行完后执行
String参数正是doInBackground的返回值,并且这个是执行在UI线程上的,可以对UI进行更新。

进一步改进

在点击按钮之后,旋转屏幕,会发现UI无法正常更新,这是因为旋转屏幕重建了UI,但是AsyncTask会在后台正常运行,但是无法更新UI,若想正常更新,需要AsyncTaskLoader

可参考我的:(未来补上 哈哈哈哈)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值