当前位置: 代码网 > it编程>App开发>Android > Android网络通信基础类源码分析讲解

Android网络通信基础类源码分析讲解

2024年05月28日 Android 我要评论
应用通信基础架构相关类源码解析这里主要对android app开发时,常用到的一些通信基础类进行一下源码的简单分析,包括:handler:处理器,与某个looper(一个线程对应一个looper)进行

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

这里主要对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网络通信的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com