VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Android >
  • Android网络通信基础类源码分析讲解

这篇文章主要介绍了Android网络通信基础类源码,包括了Handler、Looper、Thread的分析讲解,对日常开发学习很有帮助,需要的朋友可以参考下

应用通信基础架构相关类源码解析
这里主要对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网络通信的资料请关注

原文链接:https://linduo.blog.csdn.net/article/details/137404044


相关教程