Android_非UI:AsyncTask

介绍和注意事项

AsyncTask是异步处理数据的类,相当于Thread+Handler的封装,内部维护了线程池ThreadPoolExecutor,主要有4个方法,onPreExecute() doInBackground() onProgressUpdate() onPostExecute(),执行顺序也是这么排列的,只有doInBackground()是必须要实现的,因为它是由abstrct修饰。

  • AsyncTask的执行必须在UI线程,因为其内部维护了Handler,而handleMessage()处理消息必须在UI线程。

  • AsyncTask只能执行一次,执行多次会抛出异常java.lang.IllegalStateException: Cannot execute task: the task is already running.
    如连续2次调用execute()就会报错。

task.execute();
task.execute();

内部方法介绍

这4个方法中,也只有doInBackground()方法是在子线程中执行的,其余3个都是在UI线程。

4个方法执行是有先后顺序的,而且是自动执行的,不需要使用对象调用这些方法。

另外还有2个方法:onCancelled(String s) onCancelled(),在task取消的时候调用(task.cancel(true))

  • onPreExecute()
    task执行前调用,比如设置progress的最大值和初始化值。在UI线程执行
  • doInBackground()
    执行具体的任务,在子线程中执行,通过pulishProgress()发送任务进度值
  • onProgressUpdate()
    接受pulishProgress()发送的进度值。在UI线程执行
  • onPostExecute()
    任务执行结束后调用该方法。在UI线程执行

其中onProgressUpdate(Integer... values)参数是Array,一般只取第一个值:values[0]

判断各方法是否在主线程中执行?

在各方法中打印出当前Thread的name

Thread.currentThread().getName()
AsyncTask<String, Integer, String> task = new AsyncTask<String, Integer, String>() {
    @Override
    protected String doInBackground(String... params) {
        LogUtil.d("doInBackground:" + Thread.currentThread().getName());
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        LogUtil.d("onPreExecute:" + Thread.currentThread().getName());
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        LogUtil.d("onPostExecute:" + Thread.currentThread().getName());
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        LogUtil.d("onProgressUpdate:" + Thread.currentThread().getName());
    }

    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
        LogUtil.d("onCancelled:" + Thread.currentThread().getName());
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
        LogUtil.d("onCancelled:" + Thread.currentThread().getName());
    }
}.execute();

AsyncTask缺陷

  1. 生命周期不好控制
    AsyncTask生命周期方法要么自己走完,要么调用cancle()取消task。由于AsyncTask是对Thread和Handler的封装,thread是不好控制的。当Activity被销毁的时候,应该让AsyncTask取消这个任务,但是它的doInBackGround()可能没有执行完,那么走到onPostExecute()时更新ui,会发现view=null,报错
  2. 容易引起内存泄露
    如果在Activity内部生命一个AsyncTask内部类,由于AsyncTask的生命周期比较长,当Activity被销毁的时候,AsyncTask没走完,还持有该Acitivity的引用,导致Actiivty无法被回收,引起内存泄露。
  3. 数据丢失
    横竖屏切换的时候,AsyncTask持有的Activity的引用就无效了,无法更新ui。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值