文章目录

  • 一、主线程中的 Handler 与 Looper
  • 二、Handler 原理简介

一、主线程中的 Handler 与 Looper


Android 系统中 , 点击图标启动一个应用进程 , 就是从 Linux 的 Zygote 进程 fork 一个子进程 , 之后该子进程就会创建 ActivityThread , 执行其中的 main 函数 , 该 main 函数就是应用的主线程 ;

Android 的主线程在 ActivityThread 中创建并维护 , 在该类中的 main 函数 , 就是 Activity 中的主函数 ;

在该主函数中 , 调用 Looper.prepareMainLooper() 准备主线程 Looper ;

在最后的地方调用 Looper.loop() , 无限循环消息队列中的消息 ;

public final class ActivityThread extends ClientTransactionHandler {public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");// CloseGuard defaults to true and can be quite spammy.  We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");// 获取主线程 Handler 对应的 Looper Looper.prepareMainLooper();// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.// It will be in the format "seq=114"long startSeq = 0;if (args != null) {for (int i = args.length - 1; i >= 0; --i) {if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq = Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// 无限循环获取任务并执行 Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
}

源码参考 : android/9.0.0_r8/xref/frameworks/base/core/java/android/app/ActivityThread.java

二、Handler 原理简介


Handler 主要作用是 , 用于 线程间通信 ,

在线程 AAA 中创建 Handler , 在其它线程中使用 Handler 对象发送消息给 AAA 线程的 MessageQueue 消息队列 ,

线程 AAA 中的 Looper 不停地从 消息队列 ( MessageQueue ) 中取出 Message 消息 , 然后进行分发 ;

在线程 AAA 中使用 Handler , 首先要调用 Looper.prepare()方法 , 该方法的作用是准备轮询器 ,

Looper 创建后 , 会放在 ThreadLocal 中 , 这是线程的变量表 , 每个线程都有一个线程 ThreadLocal ,

使用线程 AAA 时 , 拿到 AAA 线程的 Looper , 在其它线程中调用 Handler 的 sendMessage 方法 ,

将消息传递给线程 AAA 中的 消息队列 ( MessageQueue ) 中 ,

Looper 中维护了一个 消息队列 ( MessageQueue ) , MessageQueue 封装在 Looper 中 ;

更多细节参考 : 【Android】Handler 机制 ( Handler | Message | Looper | MessageQueue )

【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )相关推荐

  1. [转]Android限制只能在主线程中进行UI访问的实现原理

    目录 Android限制只能在主线程中进行UI访问 Thread的实现 Android Thread 的构造方法 Android Thread 的start()方法 如何在我们自己的代码中去检测当前T ...

  2. 【Android面试】主线程中的Looper.loop()一直无限循环为什么不会造成ANR?

    Android面试中,你也许会被问到题目中的问题,这里我们基于以下几点来延伸解读其中原因: 1.什么是ANR?ANR发生的原因是什么? 2.Looper为什么要无限循环? 3.线程的几种状态 4.主线 ...

  3. 多线程,主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage

    android是单线程的,在子线程中是不能修改UI线程的任何操作,所以要用一种方式让子线程中的信息返回到主线程中再做修改.这就要让主线程与子线程通信. 那如何让它们之间进行通信呢?我们用Handler ...

  4. 用Handler的post()方法来传递线程中的代码段到主线程中执行

    自定义的线程中是不能更新UI的,但是如果遇到更新UI的事情,我们可以用handler的post()方法来将更新UI的方法体,直接传送到主线程中,这样就能直接更新UI了.Handler的post()方法 ...

  5. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

  6. Android Handler主线程和一般线程通信的应用分析

    Handler的定义:主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进 ...

  7. android handler 主线程吗,[android开发]非主线程进行handler操作

    [android开发]非主线程进行handler操作 (2012-10-30 16:26:01) 标签: 杂谈 android默认对主线程创建有消息队列及looper(looper是对消息队列的操作类 ...

  8. 既然android service是运行在主线程中的,那service还有什么用?

    既然android service是运行在主线程中的,那service还有什么用? 对于Android,每一个进程都有一个主线程,四大组件的处理任务都是在这个线程中进行的.每个线程都有一个Messag ...

  9. Android线程之主线程向子线程发送消息

    和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...

最新文章

  1. Zynq的AMP开发注意事项之sdk_repo
  2. IDEA的UML图介绍(一)
  3. 14-CoreData兼容iOS9和iOS10
  4. jquery toggle()设置
  5. Java基础--访问权限控制符
  6. MySql 高频企业面试题
  7. c语言编译错误c267,为啥编译出现HAHA.C(31): error C267: 'adc0832': requires ANSI-style prototype.......
  8. windows 10 主题美化
  9. 实验七 TCP/IP协议分析
  10. win10 隐藏图标
  11. 霏霏暮雨 eclipse+HBASE开发环境搭建(已实践
  12. 专升本英语——语法知识——基础语法——第一节 名词和代词【学习笔记】
  13. win7系统自带的录像在哪里 Win7问题步骤记录器教程详解
  14. 男孩子学计算机好不好,适合男孩学的专业 男生最吃香的专业
  15. 【VRP问题】基于遗传算法求解带容量的VRP问题matlab源码
  16. 零基础HTML入门教程(11)——换行br
  17. python:shape和reshape函数基本讲解
  18. MATLAB中nargin函数的用法nargin是用来判断输入变量个数的函数,这样就可以针对不同的情况执行不同的功能。通常可以用它来设定一些默认值。如下例所示: 函数文件 examp.m
  19. 如何批量图片重命名不同名字?
  20. 华为防火墙虚拟系统的案例分析(个人总结向)

热门文章

  1. SWFLibrary类加载外部资源库
  2. Python学习之路-12 (递归)
  3. salesforce 零基础学习(四十二)简单文件上传下载
  4. Chrome插件(Extensions)开发实践
  5. 【poj3734】矩阵乘法求解
  6. hdu 5037 周期优化
  7. 第二阶段第七次站立会议
  8. python学习之----获取标签属性
  9. centos修改主机名整理(勿喷)
  10. Eclipse插件工具