美文网首页
Handler 源码解读

Handler 源码解读

作者: Android_小马范儿 | 来源:发表于2019-03-24 15:15 被阅读0次

    首先定义三个个Hander,一个在主线程的Handler,两个个在子线程的Handler

    • 在主线程的Handler定义如下
       Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == MSG_MAIN) {
                    LogUtils.e(TAG, "handler1====" + Thread.currentThread().getName());
                }
                super.handleMessage(msg);
            }
        };
    
    Message message = handler.obtainMessage();
                    message.what = MSG_MAIN;
                    handler.sendMessage(message);
    
    

    执行后的日志如下

     handler1====main
    
    • 在子线程的Handler定义如下
     new Thread(new Runnable() {
                        @Override
                        public void run() {
                            handler2 = new Handler(Looper.getMainLooper()) {
                                @Override
                                public void handleMessage(Message msg) {
                                    super.handleMessage(msg);
                                    if (msg.what == MSG_THREAD) {
                                        LogUtils.e(TAG, "handler2========" + Thread.currentThread().getName());
                                    }
                                }
                            };
    
                            Message message2 = handler2.obtainMessage();
                            message2.what = MSG_THREAD;
                            handler2.sendMessage(message2);
    
                        }
                    }).start();
    

    执行后日志如下:

     handler2========main
    
    • 在子线程定义的Handler如下
     new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Looper.prepare();
                            Handler handler3 = new Handler() {
                                @Override
                                public void handleMessage(Message msg) {
                                    super.handleMessage(msg);
                                    if (msg.what == MSG_THREAD_NEW) {
                                        LogUtils.e(TAG, "handler3========" + Thread.currentThread().getName());
                                    }
                                }
                            };
                            handler3.sendEmptyMessage(MSG_THREAD_NEW);
                            Looper.loop();
                        }
                    }).start();
    

    执行后日志如下:

    handler3========Thread-5
    

    总结:主线程可以直接使用定义Handler且执行在主线程,如果在子线程定义Handler,并使用Hanlder(Looper.getMainLooper()),则发送的消息也是在主线程执行;如果在子线程定义Handler使用,需要使用Loop.prepare();定义完Handler后,Loop.loop(),则发送的消息在子线程执行

     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 " + Thread.currentThread()
                            + " that has not called Looper.prepare()");
            }
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }
    
    • 创建Handler时,要确定Looper是否为null,如果是null,则报错
     /**
         * Return the Looper object associated with the current thread.  Returns
         * null if the calling thread is not associated with a Looper.
         */
        public static @Nullable Looper myLooper() {
            return sThreadLocal.get();
        }
    
    • 获取Looper是通过ThreadLocal<Looper> 变量获取,子线程使用Handler时,Looper.prepare(),是初始化
        private static void prepare(boolean quitAllowed) {
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }
    

    主线程为什么不需要Looper.prepare,因为在ActivityThread的Main方法中,有初始化

     public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    
            // CloseGuard defaults to true and can be quite spammy.  We
            // disable it here, but selectively enable it later (via
            // StrictMode) on debug builds, but using DropBox, not logs.
            CloseGuard.setEnabled(false);
    
            Environment.initForCurrentUser();
    
            // Set the reporter for event logging in libcore
            EventLogger.setReporter(new EventLoggingReporter());
    
            // Make sure TrustedCertificateStore looks in the right place for CA certificates
            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
            TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
            Process.setArgV0("<pre-initialized>");
    
            Looper.prepareMainLooper();
    
            // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
            // It will be in the format "seq=114"
            long startSeq = 0;
            if (args != null) {
                for (int i = args.length - 1; i >= 0; --i) {
                    if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                        startSeq = Long.parseLong(
                                args[i].substring(PROC_START_SEQ_IDENT.length()));
                    }
                }
            }
            ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
    
            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();
    
    

    相关文章

      网友评论

          本文标题:Handler 源码解读

          本文链接:https://www.haomeiwen.com/subject/kfcuvqtx.html