zoukankan      html  css  js  c++  java
  • Android的线程和线程池

    ---恢复内容开始---

    一、Android线程的形态

    (一)AsyncTask解析

    AysncTask简介:①、实现上封装了Thread和Handler   ②、不适合进行特别耗时的后台任务

    AysncTask使用:android AsyncTask 的使用(转载)

    AysncTask的使用限制:①、AysnTask类必须在主线程中加载。(根据后面的源码进行解析)  ②、对象必须在主线程创建  ③、execute方法必须在UI线程调用

    ④、一个AsyncTask对象只能执行一次execute(),否则会报错   ⑤、在Andorid3.0之后采用串行执行任务(串行:表示排队执行,比如说我开启了10个AysncTask下载,串行表示我只能一个一个执行),但是我们任可以通过executeOnExecutor()执行并行任务(并行:表示我能够10个AysncTask一起执行)

    AsyncTask的工作原理

    ①、首先从AsyncTask的execute()方法开始->调用executeOnExecutor()

    ②、查看executeOnExecutor()(P395 ①)

    1、sDefalutExecutor对象表示:是一个串行的线程池(该对象稍后解析)

    2、先执行AsyncTask的onPreExecute()方法

    3、之后调用sDefaultExecuotr.execute(mFuture);

    解析mFuture:为FutureTask类,首先系统会将AsyncTask的Params参数封装为FutureTask类,FutureTask是一个并发类(什么意思),这里充当了Runnable的作用。

    ③、分析sDefaultExecutor类(P396 ①)

    1、发现sDefaultExecutor是SerialExecutor类,SeriralExecutor类是一个私有的静态类

    2、在看下execute():将mFuture插入到mTask的队列中去,并判断当前有没有正在活动的AsyncTask任务,没有的话就调用scheduleNext()执行下一个AsynacTask()任务。

    当一个AsynacTask执行完会继续执行下一个。

    ④、AsyncTask中有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler)。

    SerialExecutor(用于线程的排队),THREAD_POOL_EXECUTOR(用于线程的真正执行),InternalHandler(将线程环境切换为UI环境)

    ⑤、当执行的时候,调用Future.run()方法中会调用mWorker的call()方法(P397 ①)

    在call()方法中:首先将mTaskInvoked.set(true)表示该任务被调用过了,之后调用doInBackground()->在调用postResult(参数为doInBackground的返回值)

    ⑥、查看postResult()的实现(P397 ①)

    发现会向sHandler发送一个MESSAGE_POST_RESULT消息

    ⑦、查看sHandler的定义(P398 ①)

    sHandler是一个静态的Handler对象,且为了能够将执行环境切换到主线程,所以必须在主线程下创建该Handler。

    sHandler收到MESSAGE_POST_RESULT消息后,就会调用AsyncTask的finish()方法

    ⑧、AsyncTask的finish()方法(P398 ②)

    这是一个判断语句:当AsyncTask被取消执行,则会调用onCancelled()。否则调用onPostExecute()所以doInBackground返回的结果给onPostExecute()且该方法是在主线程中执行的。

    关于AysncTask的串行与并行

    调用execute()表示,串行执行

    调用executeOnExecutor()表示,并行执行

    (二)、HandlerThread

    作用:继承了Thread,可以使用Handler的Thread,不用自己创建Looper,允许在Thread中创建Handler

    解析

    ①、查看run()方法(P402 ①)

    在其中创建一个Looper,其中有OnLooperPrepared()这个方法中用来加载Handler是最合适的。

    与普通Thread的区别,需要使用Handler来通知HandlerThread来执行一个任务。而普通的Thread就是在run()方法中执行一个耗时任务

    :因为启动了Looper所以必须使用Looper.quit()方法将该线程停止。

    主要使用的场景是在IntentService中

    (三)、IntentService

     简介:IntentService是一个特殊的Service,继承了Service类,并且自己本身还是一个抽象类,所以还必须继承IntentService,才能使用IntentSeravice。

    作用:IntentService可用于执行,耗时的后台任务,当任务执行完成的时候会自动停止。

    解析:

    ①、IntentService封装了HandlerThread和Handler,可以从onCreate()方法(P403 ①)。

    当IntentSerivce第一次启动的时候其onCreate()方法就会被调用一次,这样handler发送的消息就可以在HandlerThread中执行。

    ②、当每次启动IntentService时,onStartCommand()方法都会被调用,在这个地方处理Intent发送过来的事件。->调用onStart()

    ③、onStart()方法的实现(P404 ①)

    发现向mServiceHandler发送了一条信息,该信息会在HandlerThread中处理。mServiceHandler收到消息后,会调用onHandleIntent()。

    ④、当完成调用onHandleIntent()方法时,IntentService会尝试调用stopSelf()方法停止服务。(P404 ②)

    二、Android中的线程池

    (一)、ThreadPoolExecutor介绍

             ThreadPoolExecutor使用介绍  

    (二)、AysncTask的ThreadPoolExecutor配置

    (三)、其他种类的线程池

  • 相关阅读:
    beeline链接hive报错
    Java并发之FairSync和NonfairSync
    如何在 Linux 中将文件编码转换为 UTF-8
    Spring Boot运行原理
    jvm垃圾回收
    jvm调试工具
    Nginx相关
    docker 配置jar ,运行
    centos7的一些安装问题
    Docker
  • 原文地址:https://www.cnblogs.com/rookiechen/p/5470592.html
Copyright © 2011-2022 走看看