Android网络通信基础类源码分析讲解
目录
应用通信基础架构相关类源码解析
这里主要对Android App开发时,常用到的一些通信基础类进行一下源码的简单分析,包括:
基于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
@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();
其提供了一些方法,用于控制线程,比如
注意:Thread和Looper是两个事情,其关系是一对一。 Thread就是常规意义上的线程,程序代码最小的运行单位(先不考虑协程),Looper是一套基于消息(事件)的驱动机制。
Runnable是一个接口类,规定了Run这个方法。MessageQueue是一个消息队列。这个类功能比较单一。其源码路径如下,感兴趣的可自行了解。
再贴一遍类图,加深理解。
以上就是Android网络通信基础类源码分析讲解的详细内容,更多关于Android网络通信的资料请关注脚本之家其它相关文章!
您可能感兴趣的文章:
- .NET Core系列之MemoryCache 初识
- 007手机一键Root(安机网一键Root) v3.0 官方最新版 一键ROOT您的Android手机
- 12306密码被盗了怎么办?12306密码外泄解决方法
- 12个字的qq网名
- 150M迷你型无线路由器怎么设置?
- 192.168.1.1打不开怎么办?路由器192.168.1.1打不开的原因以及解决办法
- 2011年电子报合订本 电子报 编辑部 中文 PDF版 [84M]
- 2015年1月15日小米新旗舰发布会现场图文直播
- 2016.3.1vivo Xplay5新品发布会现场视频直播 优酷直播
- 2016华为P9发布会视频直播地址 4月15日华为P9国行发布会直播