重温Android中的线程、线程池源码

本文深入探讨了Android中线程和线程池的使用,包括AsyncTask、HandlerThread、IntentService和线程池的工作原理。通过源码分析,揭示了AsyncTask的执行流程、限制和最佳实践,解释了为何在不同场景下选择HandlerThread、IntentService的原因,以及Executor和线程池的分类与配置。
摘要由CSDN通过智能技术生成

本篇博文涉及到的一些Android中常用的线程相关知识,源码也比较简单,作为重温笔记。 

Android中的线程、线程池,,如下图所示:

 AsyncTask

                  

上述方法的执行顺序是:1 -> 2 -> 3 -> 4

对于AsyncTask有如下几点可以从源码中得到验证

  • AsyncTask的对象必须在主线程中创建(非必须,后面会讲)
  • execute方法必须在UI线程调用(非必须,后面会讲)
  • 不要在程序中直接调用onPreExecute、onPostExecute、doInBackground和onProgressUpdate方法
  • 一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常
  • AsyncTask默认是串行执行任务的,但是我们仍然可以通过AsyncTask的executeOnExecutor方法来并行地执行任务
  • AsyncTask 调用 cancel() 任务是否立即停止执行?onPostExecute() 还会被调用吗?onCancelled() 什么时候被调用?

AsyncTask的一般用法如下:

// 除了doInBackground是必须重写的方法,其他的都是可选的实现方法
public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(String... strings) {
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(Integer integer) {
        super.onPostExecute(integer);
    }

    @Override
    protected void onCancelled(Integer integer) {
        super.onCancelled(integer);
    }
}
===============================================================
        MyAsyncTask myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute();// 同步执行

        myAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");// 并发执行
        myAsyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, "");// 同步执行

源码解读:

如下两点是非必须的:

  • AsyncTask的对象必须在主线程中创建
  • execute方法必须在UI线程调用

之前看过一些网上的资料还有一些书籍,都说如上的1,2条。但是并未详细的解释为什么要这样。阅读了AsyncTask的源码你会发现,强制要求上面两点是错误的。为什么呢?看源码

/**
 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
 */
public AsyncTask() {
  this((Looper) null);
}


   /**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     *
     * @hide  // 1
     */
public AsyncTask(@Nullable Handler handler) {
    this(handler != null ? handler.getLooper() : null);
}
  
   /**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     *
     * @hide // 2
     */
public AsyncTask(@Nullable Looper callbackLooper) {
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);

        ......
    }

如上源码中的1和2处,@hide意味着这两个构造方法是系统使用的而不是给开发者准备的,开发者只能使用第一个无参的构造方法。无参的构造方法会调用上述源码最后一个构造方法,保证了我们可以拿到主线程的Looper。

我们知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值