美文网首页Android汇总总结
关于Android线程与Handler的理解。

关于Android线程与Handler的理解。

作者: Cooke_ | 来源:发表于2016-09-27 13:41 被阅读62次

    概述

    我们都知道,更新UI只能在主线程中操作,若是在子线程中访问UI控件,容易引起阻塞。
    问题来了,什么是主线程,什么是子线程?

    主线程

    主线程是指进程所拥有的线程。当一个android程序启动时,会单独启动一个进程,默认情况下只有一个。程序启动时,进程会启动一个主线程,也就是UI线程,主要是负责控制UI界面的显示、更新和控件交互。Android的主线程就是ActivityThread,主线程的入口方法为Main,在main方法中系统会通过Looper.prepareMainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop()来开启主线程的消息循环。看一下过程。

        public static ActivityThread currentActivityThread() {  
            return sThreadLocal.get();  
        }  
      
       
        public static void main(String[] args) {  
            SamplingProfilerIntegration.start();  
      
            // 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());  
      
            Process.setArgV0("<pre-initialized>");  
      
            Looper.prepareMainLooper();  
      
            // 创建ActivityThread实例  
            ActivityThread thread = new ActivityThread();  
            thread.attach(false);  
      
            if (sMainThreadHandler == null) {  
                sMainThreadHandler = thread.getHandler();  
            }  
      
            AsyncTask.init();  
      
            if (false) {  
                Looper.myLooper().setMessageLogging(new  
                        LogPrinter(Log.DEBUG, "ActivityThread"));  
            }  
      
            Looper.loop();  
      
            throw new RuntimeException("Main thread loop unexpectedly exited");  
        }  
    }  
    

    子线程

    子线程主要负责一些耗时任务的执行,再配合主线程进行UI的更新。
    子线程默认是没有Looper的,若是使用Handler进行消息的传递,需要手动进行创建Looper

    new Thread(){
    @override
    public void run(){
    Looper.prepare();//创建Looper对象
    Handler handler = new Handler();//这种构造方式会默认使用当前线程的Looper
    Looper.loop();//Looper开始工作
      }
    }.start();
    

    但这种情况下是不能通过handler更新UI的,因为handler并没有实例化在主线程中。这时值能处理非更新UI的的操作。如果你想在这个子线程中更新UI的话,需要这么做

    Handler handler = new Handler(Looper.getMainLooper());
    

    这种构造方式引用了主线程的Looper,表示放到主UI线程去处理,所以可以更新UI。

    判断当前线程是否为主线程。

    • 方法一:使用Looper类判断
      Looper.myLooper() == Looper.getMainLooper();

    • 方法二:通过查看Thread类的当前线程
      Thread.currentThread() == Looper.getMainLooper().getThread()

    相关文章

      网友评论

        本文标题:关于Android线程与Handler的理解。

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