应用通信基础架构相关类源码解析
这里主要对android app开发时,常用到的一些通信基础类进行一下源码的简单分析,包括:
- handler:处理器,与某个looper(一个线程对应一个looper)进行关联。用于接收消息,并在关联的looper,处理消息。
- looper:驱动器,驱动基于事件的消息系统(通信架构的核心)其实现在native层,基于epoll机制(感兴趣的可自行了解)。
- runnable: 表示“可执行的代码”,本质是interface,规定了run这个接口。
- messagequeue: 消息队列,提供了入队、出队等操作。一个线程,只能有一个messagequeue。
- thread: 线程类,封装了线程相关操作。
基于android12代码。
类图:

handler
常见用法
private handler mhandler = new handler(looper.getmainlooper()) {
@override
public void handlemessage(message msg) {
// 处理消息
}
};
private void sendmessage() {
// 发送消息
message msg = mhandler.obtainmessage();
// 填充msg
mhandler.sendmessage(msg);
}
private void postrunnable() {
// 告知handler一段可执行的代码(runnable)
mhandler.post(new runnable() {
@override
public 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());
}
}
// 获取当前线程对应的looper
mlooper = looper.mylooper();
if (mlooper == null) {
throw new runtimeexception(
"can't create handler inside thread " + thread.currentthread()
+ " that has not called looper.prepare()");
}
// 使用looper中的messagequeue
mqueue = 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;
// 记录一下uid
msg.worksourceuid = threadlocalworksource.getuid();
if (masynchronous) {
msg.setasynchronous(true);
}
// 消息入队messagequeue
return 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().
@unsupportedappusage
static final threadlocal<looper> sthreadlocal = new threadlocal<looper>();
@unsupportedappusage
private 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
再贴一遍类图,加深理解。

以上就是android网络通信基础类源码分析讲解的详细内容,更多关于android网络通信的资料请关注代码网其它相关文章!
发表评论