handler源码浅析

1.handler构造过程

public Handler() {
        this(null, false);
    }

该构造函数最终会调用

 public Handler(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());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

这分别为 成员变量 mLooper = Looper.myLooper();和 mQueue = mLooper.mQueue; 赋值

2.mLooper 获取过程
通过 Looper.myLooper(); 得到

public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

get()方法实现 看注释

 public T get() {
        // Optimized for the fast path.
        Thread currentThread = Thread.currentThread();
        // 获取当前线程的values
        Values values = values(currentThread);
        if (values != null) {
        // 得到threadLocal数组
            Object[] table = values.table;
            int index = hash & values.mask;
            if (this.reference == table[index]) {// 弱引用与数组中的threadLocal是同个引用
                return (T) table[index + 1];
            }
        } else {
        // 初始化values
            values = initializeValues(currentThread);
        }
        // 得到value
        return (T) values.getAfterMiss(this);
    }

3.mQueue 获取过程

mQueue = mLooper.mQueue;

mQueue在Looper的私有构造函数中初始化

 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

私有构造函数在prepare(boolean quitAllowed) 调用

 private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        // 创建出looper
        sThreadLocal.set(new Looper(quitAllowed));
    }

repare(boolean quitAllowed) 方法 在 prepareMainLooper()中调用

public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

prepareMainLooper()方法 在ActivityThread 的main中调用

// ....
  Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");

消息队列初始化完成

在main方法中调用Looper.loop();
loop()实现

 public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            msg.target.dispatchMessage(msg);

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    }

这注意for循环 Message msg = queue.next(); 是一个阻塞方法

msg.target.dispatchMessage(msg); 这句是处理系统消息

  public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

回调子类实现的方法mCallback.handleMessage(msg)

Netty Socks5客户端是基于Netty框架实现的一个Socks5代理客户端。它可以通过发送初始化请求、认证请求和建立连接三个部分来与Socks5代理服务器进行通信。首先,客户端会发送初始化请求,并选择不需要认证的方式进行连接。然后,如果需要进行用户名和密码认证,客户端会发送认证请求,并返回认证成功的响应。最后,客户端会发送建立连接的请求,并将请求转发到代理服务器,再由代理服务器将请求转发给目标服务器。通过使用Netty的Socks5ProxyHandler处理器,客户端可以直接连接到代理服务器并与目标服务器进行通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Netty的客户端使用Socks5代理,netty-handler-proxy源码浅析](https://blog.youkuaiyun.com/weixin_43859729/article/details/129884862)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [netty系列之:从零到壹,搭建一个SOCKS代理服务器](https://blog.youkuaiyun.com/superfjj/article/details/122208732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值