时间:2021-02-15 10:22:19 | 栏目:Android代码 | 点击:次
Android 的线程和线程池
从用途上分,线程分为主线程和子线程;主线程主要处理和界面相关的事情,子线程则往往用于耗时操作。
主线程和子线程
主线程是指进程所拥有的线程。Android 中主线程交 UI 线程,主要作用是运行四大组件以及处理它们和用户的交互;子线程的作业则是执行耗时任务。
Android 中的线程形态
1、AsyncTask AsyncTask 是一种轻量级的异步任务类,可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新 UI, AsyncTask 是一个抽象的泛型类,提供了 Params(参数的类型)、Progress(后台任务执行进度的类型) 和 Result(后台任务的返回结果的类型) 这三个泛型参数, AsyncTask 提供了4个核心方法
onPreExcute 先执行,接着是 doInBackground,最后才是 onPostExecute。 当异步任务被取消时,onCancelled() 方法会被调用,这个时候 onPostExecute 则不会被调用。
2、AsyncTask 在具体的使用过程中的一些限制条件
3、AsyncTask 的工作原理 AsyncTask 中有两个线程池(SerialExecutor 和 THREAD_POOL_EXECUTOR) 和一个 Handler(InternalHandler),线程池 SerialExecutor 用于任务的排队,线程池 THREAD_POOL_EXECUTOR 用于真正地执行任务,InternalHandler 用于将执行环境从线程池切换到主线程。
4、HandlerThread HandlerThread 继承了 Thread,是一种可以使用 Handler 的 Thread, 它的实现就是在 run 方法中通过 Looper.prepare() 来创建消息队列,并通过 Looper.loop() 来开启消息循环。
与普通的 Thread 相比,普通 Thread 主要用于在 run 方法中执行一个耗时任务,而 HandlerThread 在内部创建了消息队列,外界需要通过 Handler 的消息方式来通知 HandlerThread 执行一个具体的任务。
由于 HandlerThread 的 run 方法是一个无限循环,因此当明确不需要在使用 HandlerThread 时,可以通过它的 quit 或者 quitSafely 方法来终止线程的执行。
5、IntentService IntentService 是一种特殊的 Service,继承了 Service 并且是一个抽象类,必须创建它的子类才能使用 IntentService。IntentService可用于执行后台耗时任务,任务执行后会自动停止,并且它的优先级比单纯的线程要高很多,不容易被系统杀死。在实现上,IntentService 封装了 HandlerThread 和 Handler。
Android 中的线程池
线程池的优点
ThreadPoolExecutor ThreadPoolExecutor 是线程的真正实现。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
ThreadPoolExecutor 执行任务时遵循的规则
线程池的分类
系统预置4种线程池的典型使用方法:
Runnable command = new Runnable(){ @Override public void run(){ SystemClock.sleep(2000); } ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); fixedThreadPool.execute(command); ExecutorService cachedThreadPool =Executors.newCachedThreadPool(); cachedThreadPool.execute(command); ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4); // 2000ms 后执行 command scheduledThreadPool.schedule(command,2000,TimeUnit.MILLISECONDS); // 延迟10ms,每个1000ms执行一次 command scheduledThreadPool.scheduleAtFixedRate(command,10,1000,TimeUnit.MILLISECONDS); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(command); }