应用通信基础架构相关类源码解析
这里主要对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网络通信的资料请关注代码网其它相关文章!
发表评论