在主线程中创建的处理程序的行为就像在另一个线程上一样

时间:2018-06-27 12:27:36

标签: android multithreading handler

正如Google所说:

  

处理程序允许您发送和处理Message和Runnable对象   与线程的MessageQueue相关联。每个处理程序实例为   与单个线程和该线程的消息队列相关联。什么时候   您创建一个新的处理程序,它绑定到的线程/消息队列   创建它的线程-从那时起,它将交付   消息和可运行对象到该消息队列,并在它们执行时执行   从消息队列中出来。

我希望当我在主线程(UI线程)中创建一个Handler时,它将附加到该线程,从而导致冻结ui直到结束其任务。但是在测试中不会发生这种情况,它的行为就像是在backgound线程上并并行执行其任务。 我以前是这样创建Handle的:

<action name="Hive">
    <hive>
        <job-tracker>${job_tracker}</job-tracker>
        <name-node>${name_node}</name-node>
        <script>${wf:actionData('Query')['Location']}</script>
         <param>JOBDIR=${jobDir}</param>            
        <configuration>             
            <property> 
                <name>oozie.launcher.mapred.child.java.opts</name> 
                <value>-Xmx512m</value> 
            </property>                 
            <property> 
                <name>mapred.map.child.java.opts</name> 
                <value>-Xmx1024m</value> 
            </property> 
            <property> 
                <name>mapred.reduce.child.java.opts</name> 
                <value>-Xmx1024m</value> 
            </property>
                  <name>mapred.max.split.size</name>
                  <value>2560000</value>
                  <description>Largest valid size in bytes for a file split.
                        This should be set to a small multiple of the block size in bytes
                  </description> 
            </property>             
        </configuration>            
    </hive>

在mainActivity中(因此句柄应绑定到Main线程)。那么,这是什么问题呢?还是我以错误的方式创建了处理程序?

有些朋友注意到 Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < 35000; i++) { log.i(TAG,"log in Handler:"+i); }} }; mainHandler.post(runnable); log.i(TAG,"log outSide"); 还不够复杂,但是如果我们在同一个线程中,为什么我们在“登录处理程序:”之前看到“ logoutSide”。

2 个答案:

答案 0 :(得分:0)

实际上,它按预期工作,您的处理程序当前与您的主线程相关联,因为它是在主线程中创建的,并且您的任务也在同一线程上运行。尝试在for循环中添加 Thread.sleep(1000)方法,然后您会在UI中看到冻结。 由于您的N是常数,因此您当前的代码以O(1)的复杂度运行,并且您的手机能够在几分之一秒的时间内运行此代码,这就是为什么您在测试期间未观察到UI冻结的原因。

答案 1 :(得分:0)

一些朋友注意到doSomthing()还不够复杂,但是如果我们在同一线程中,为什么我们会在“登录处理程序:”之前看到“ logoutSide”。

这是因为将Runnable传递到Handler的延迟。即使处理程序是使用主线程的循环程序创建的,在调用post与将处理程序消息放入处理程序的队列中并在线程上执行之间,仍然存在少量延迟。

“外部日志”会立即运行,因此您可以在Handler内的日志之前看到该日志。