【Android】App通信基础架构相关类源码解析

应用通信基础架构相关类源码解析

这里主要对Android App开发时,常用到的一些通信基础类进行一下源码的简单分析,包括:

  • Handler:处理器,与某个Looper(一个线程对应一个Looper)进行关联。用于接收消息,并在关联的Looper,处理消息。
  • Looper:驱动器,驱动基于事件的消息系统(通信架构的核心)其实现在Native层,基于epoll机制(感兴趣的可自行了解)。
  • Runnable: 表示“可执行的代码”,本质是Interface,规定了Run这个接口。
  • MessageQueue: 消息队列,提供了入队、出队等操作。一个线程,只能有一个MessageQueue。
  • Thread: 线程类,封装了线程相关操作。

基于Android12代码。

类图:
在这里插入图片描述

Handler

常见用法

private Handler mHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {// 处理消息}
};private void sendMessage() {// 发送消息Message msg = mHandler.obtainMessage();// 填充msgmHandler.sendMessage(msg);
}private void postRunnable() {// 告知Handler一段可执行的代码(Runnable)mHandler.post(new Runnable() {@Overridepublic void run() {// do something}});
}

通过上述代码中,可以看出。创建Handler时需要绑定Looper,也就是绑定到运行的线程上。如过不指定looper,使用创建handler时所在线程的Looper。
源码定义在 frameworks/base/core/java/android/os/Handler.java

public Handler() {this(null, false);
}public Handler(@NonNull Looper looper) {this(looper, null, false);
}public Handler(@Nullable Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}// 获取当前线程对应的LoopermLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread " + Thread.currentThread()+ " that has not called Looper.prepare()");}// 使用Looper中的MessageQueuemQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;
}@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {mLooper = looper;mQueue = looper.mQueue;mCallback = callback;mAsynchronous = async;
}

调用Handler的sendMessage,到Handler处理(handleMessage)这个Message。Handler会将这个Message,入队到绑定的Looper的MessageQueue(消息队列中)。

public final boolean sendMessage(@NonNull Message msg) {// 没有延时 return sendMessageDelayed(msg, 0);
}public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);
}private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis) {msg.target = this;// 记录一下UIDmsg.workSourceUid = ThreadLocalWorkSource.getUid();if (mAsynchronous) {msg.setAsynchronous(true);}// 消息入队MessageQueuereturn queue.enqueueMessage(msg, uptimeMillis);
}

Looper从MessageQueue中依次取出Message,并告知Handler的handleMessage处理消息(想要看懂looper,涉及到其Native实现,这里不分析,可自行了解)

Looper

Looper类基于epoll机制,提供了一套事件驱动机制。Java层的实现在frameworks/base/core/java/android/os/Looper.java,该类中的sMainLooper变量存储了 主线程(或者叫UI线程)对应的Looper,可以通过getMainLooper取得。

public final class Looper {private static final String TAG = "Looper";// sThreadLocal.get() will return null unless you've called prepare().@UnsupportedAppUsagestatic final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();@UnsupportedAppUsageprivate static Looper sMainLooper;  // guarded by Looper.class// 省略public static Looper getMainLooper() {synchronized (Looper.class) {return sMainLooper;}}
}

常见的用法,比如在自定义的线程中。

public class MyThread extends Thread {  private Handler mHandler;  @Override  public void run() {  Looper.prepare(); // 准备Looper  mHandler = new Handler() {  @Override  public void handleMessage(Message msg) {  // 处理消息  }  }  };  Looper.loop(); // 开始循环,等待消息  }
}

Looper的实现这里就不分析了,路径在**/frameworks/base/core/java/android/os/Looper.java**,可自行了解(建议先掌握epoll)

Thread

Android Thread类提供线程功能,其定义在 libcore/ojluni/src/main/java/java/lang/Thread.java

public
class Thread implements Runnable {public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}
}

调用start方法,可以启动线程,比如上面定义的MyThread类。

MyThread thr = new MyThread();
thr.start();

其提供了一些方法,用于控制线程,比如

  • sleep: 让线程等待一段时间
  • jion:等待线程退出(或者叫执行完成)
  • interrupt:打断线程。

注意:Thread和Looper是两个事情,其关系是一对一。 Thread就是常规意义上的线程,程序代码最小的运行单位(先不考虑协程),Looper是一套基于消息(事件)的驱动机制。

Runnable是一个接口类,规定了Run这个方法。MessageQueue是一个消息队列。这个类功能比较单一。其源码路径如下,感兴趣的可自行了解。

  • /frameworks/base/core/java/android/os/MessageQueue.java
  • /libcore/ojluni/src/main/java/java/lang/Runnable.java

再贴一遍类图,加深理解。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/302448.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Vue的大学生体质测试管理系统(源码+文档+部署+讲解)

一.系统概述 大学生体质测试管理系统提供给用户一个简单方便体质测试管理信息&#xff0c;通过留言区互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技术以及MYSQL作为后台数据库进行开发。系统主要分为系统管理员、教师和用户三个部分&#xff0c;系统管理员主…

四级作文模板——议论文——现象解释

议论文类型 现象解释 第一句 with the rapid development of society / economy / education / technology / culture / medical / service(任选) , it is of great necessity for youngster / students to improve our speaking ability.随着社会/经济/教育/科技/文化/医疗…

redis 集群模式(redis cluster)介绍

目录 一 redis cluster 相关定义 1&#xff0c; redis cluster 是什么 2&#xff0c;redis 集群的组成 3&#xff0c;集群的作用 4&#xff0c;集群架构图 二 Redis集群的数据分片 1&#xff0c;哈希槽是什么 2&#xff0c;哈希槽如何排布 3&#xff0c;Redis集…

Economic Census

Economic Census 经济普查&#xff0c;企业需提交文档&#xff08;1-6&#xff09;&#xff0c;或者汇总扫描提交

【Spring Cloud Alibaba】9 - OpenFeign集成Sentinel实现服务降级

目录 一、简介Sentinel 是什么如何引入Sentinel 二、服务搭建1.安装Sentinel控制台1.1 下载1.2 启动1.3 访问 2.改造服务提供者cloud-provider服务2.1 引入依赖2.2 添加API2.3 添加配置文件 3.改造cloud-consumer-feign服务3.1 引入依赖3.2 添加Feign接口3.3 添加服务降级类3.4…

2023.4.7 机器学习周报

目录 引言 Abstract 文献阅读 1、题目 2、引言 3、过去方案和Motivation 4、Segment Anything模型 5、创新点 6、实验过程 7、实验结果 1、评价绩效 2、检测评价 3、跟踪评价 8、 结论 总结 引言 本周阅读了一篇关于高效的任意分割模型的文献&#xff0c;用于自…

Splunk Attack Range:一款针对Splunk安全的模拟测试环境创建工具

关于Splunk Attack Range Splunk Attack Range是一款针对Splunk安全的模拟测试环境创建工具&#xff0c;该工具完全开源&#xff0c;目前由Splunk威胁研究团队负责维护。 该工具能够帮助广大研究人员构建模拟攻击测试所用的本地或云端环境&#xff0c;并将数据转发至Splunk实例…

Pytest插件pytest-selenium-让自动化测试更简洁

在现代Web应用的开发中&#xff0c;自动化测试成为确保网站质量的重要手段之一。而Pytest插件 pytest-selenium 则为开发者提供了简单而强大的工具&#xff0c;以便于使用Python进行Web应用的自动化测试。本文将深入介绍 pytest-selenium 插件的基本用法和实际案例&#xff0c;…

达梦数据库的V$DM_INI和V$PARAMETER系统视图

V$DM_INI和V$PARAMETER是达梦数据库中两个常用的系统视图&#xff0c;用于查看数据库的配置参数。这两个视图的主要区别在于它们展示参数的来源和用途。 V$DM_INI V$DM_INI视图主要用于展示数据库启动时加载的初始化参数信息。这些信息通常来自于数据库的初始化参数文件&…

VSCode+Cmake 调试时向目标传递参数

我有一个遍历文件层次结构的程序&#xff0c;程序根据传入的文件路径&#xff0c;对该路径下的所有文件进行遍历。这个程序生成一个名为 ftw 的可执行文件&#xff0c;如果我要遍历 /bin 目录&#xff0c;用法为&#xff1a; ftw /bin问题是&#xff0c;如果我想单步跟踪&…

docker + miniconda + python 环境安装与迁移(简化版)

本文主要列出从安装dockerpython环境到迁移环境的整体步骤。windows与linux之间进行测试。 详细版可以参考&#xff1a;docker miniconda python 环境安装与迁移&#xff08;详细版&#xff09;-CSDN博客 大概过程手绘了一下&#xff1a; 一、docker 安装 略过&#xff0c…

数据库之DQL操作(数据查询语言)

DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。查询关键字: SELECT。 本节介绍以下表为例&#xff1a; create table emp(id int comment 编号&#xff0c;workno varchar(10) comment 工号&#xff0c;nam…

Kafka参数介绍

官网参数介绍:Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/documentation/#configuration

java中使用雪花算法(Snowflake)为分布式系统生成全局唯一ID

&#xff08;全局唯一ID的解决方案有很多种&#xff0c;这里主要是介绍和学习Snowflake算法&#xff09; 什么是雪花算法&#xff08;Snowflake&#xff09; 雪花算法&#xff08;Snowflake Algorithm&#xff09;是由Twitter公司在2010年左右提出的一种分布式ID生成算法&…

并查集-合并集合

#include<iostream> using namespace std; const int N 100010;int n, m; int p[N]; int find(int x)//返回x的祖宗节点路径压缩 {if (p[x] ! x)p[x] find(p[x]);return p[x]; } int main() {scanf("%d%d", &n, &m);for (int i 1; i < n; i)p[i]…

html写一个登录注册页面

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册登录界面Ⅰ</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.mi…

一闪论文靠谱吗 #媒体#笔记

一闪论文是一个以其高效、靠谱的特点而闻名的论文写作工具&#xff0c;它不仅可以帮助用户快速完成论文&#xff0c;还能够有效降低查重率&#xff0c;是许多学生和学者的首选。 首先&#xff0c;一闪论文的操作简单方便&#xff0c;用户只需上传论文内容&#xff0c;选择需要查…

linux上使用redis-cli登录以及操作redis

1、找到redis-cli 2、输入redis-cli回车 3、登录redis 输入auth密码 4、登录成功

基于Java+SpringBoot+Vue剧场管理系统(源码+文档+部署+讲解)

一.系统概述 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针…

OSCP靶场--Nagoya

OSCP靶场–Nagoya 考点 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.214.21 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-02 08:52 EDT Nmap scan report for 192.168.214.21 Host is up (0.38s latency).…