AsyncTask(已弃用)

AsyncTask已经被正式弃用了,但是很多app还是在用它的,所以还是要看下它的用法,谷歌建议使用java.util.concurrent or Kotlin concurrency utilities 这俩替代

震惊!AsyncTask将被弃用?_rqX的博客-CSDN博客_asynctask被弃用

弃用的原因可以看看上面的博文 

作用

  • 实现多线程:在工作线程中执行任务,如 耗时任务
  • 异步通信、消息传递:实现工作线程 & 主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作,保证线程安全。

比如,适用于子线程执行耗时操作并且需要有一个结果返回给主线程,这个时候我们就可以用AsyncTask实现.

AsyncTask其实就是把Thread进行了封装,内部实现原理还是Thread+Handler

基本使用

1.继承抽象类AsyncTask类并指定泛型,根据需求实现/重写该类的方法.

AsyncTask<Params, Progress, Result>
  //我这里的泛型用的Void, Void, Boolean,当然根据需要自己选别的用
  private class MyTask extends AsyncTask<Void, Void, Boolean> {

        ....

      // 方法1:onPreExecute()
      // 作用:执行 线程任务前的操作
      // 注:根据需求复写
      @Override
      protected void onPreExecute() {
           ...
        }

      // 方法2:doInBackground()
      // 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
      // 注:必须复写,从而自定义线程任务
      @Override
      protected Boolean doInBackground(Void... params) {

            ...// 自定义的线程任务

            // 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
             publishProgress(count);
              
         }

      // 方法3:onProgressUpdate()
      // 作用:在主线程 显示线程任务执行的进度
      // 注:根据需求复写
      @Override
      protected void onProgressUpdate(Void... progresses) {
            ...

        }

      // 方法4:onPostExecute()
      // 作用:接收线程任务doInBackground()的执行结果、将result显示到UI组件
      // 注:必须复写,从而自定义UI操作
      @Override
      protected void onPostExecute(Boolean result) {

         ...// UI操作

        }

      // 方法5:onCancelled()
      // 作用:被调用cancel()之后,会走到这个函数而不是onPostExecute函数
      @Override
        protected void onCancelled(Boolean result) {
        ...
        }
  }

注意 这里面函数的传参要跟我们继承的类的参数类型保持一致.

2. 调用execute或者executeOnExecutor方法

  MyTask mTask = new MyTask();
  mTask.execute();    //mTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

区别在于后者用到了线程池。

3. cancel()方法的作用

不要以为调用了mTask.cancel(true)就可以直接取消线程了,实际上是不可以的,这个方法只相当于置一个标志位给mTask,而调用了cancel之后, 我们可以在doInBackground中用isCancelled()判断.

举个例子

@Override
protected Boolean doInBackground(Void... params) {
    
    .....
    if (isCancelled()){
        result = false;
        return result;
    }
    
    //做一些耗时操作
    dosomething();

    return .....
}

就是说,我们可以通过sCancelled()判断是否cancel被调用,如果被调用,那么就对result做一些措施,

需要根据我们自己想要实现的东西来放判断的位置和具体措施.

上面代码就是耗时前判断一次,要是耗时前就被调用cancel那很好,直接不用做耗时操作了,return掉.

然后我们在继承AsyncTask类里面重写的onCancelled()方法就有用了,因为cancel了之后retun之后不会再调用onPostExecute( ),而是会调用onCancelled()

问题讨论

别再傻傻得认为AsyncTask只可以在主线程中创建实例和调用execute方法_smileiam的专栏-CSDN博客

总结一下就是,可以在子线程中创建AsyncTask实例,并执行execute.  注意在哪个线程执行AsyncTask的execute(),onPreExecute会运行在执行在哪个线程中,onPostExecute方法还是会执行在主线程中,doInBackground方法会执行在AsyncTask创建的线程中

这个问题的核心是, Handler实例化需要用到线程的Looper,而我自己新建的Thread并没有调用Looper.prepare(),所以新开的线程Looper肯定为空,怎么会运行正常呢?

因为AsyncTask源码里Handler持有的主线程的Looper

sHandler = new InternalHandler(Looper.getMainLooper());

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值