2015-02-24 31 views
1

我正在阅读EAT书籍,并且有一个显示queueIdle利用率的代码示例。处理程序queueIdle在最后一条消息到达之前调用两次

下面的代码启动10个线程,每个新线程都会抛出10条消息。我希望在每封邮件发出之后,looper将会退出。

@Override 
public boolean queueIdle() { 
    if (mIsFirstIdle) { 
     mIsFirstIdle = false; 
     return true; 
    } 

    mConsumerHandler.getLooper().quit(); 
    return false; 
} 

“的空闲时隙能够在第一消息之前发生,消息, 之间和最后的消息之后。 “摘录自:AndersGöransson。 “高效的Android线程。”iBooks。

所以我认为,queueIdle将被调用第一条消息和最后一条消息,因此它确保每条消息都被传递。

但我得到错误,因为queueIdle意外地调用?

发送消息到处理器上的死线

是正常或示例代码是错误的?

代码示例

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Looper; 
import android.os.Message; 
import android.os.MessageQueue; 
import android.os.SystemClock; 
import android.util.Log; 

import java.util.Random; 


public class ConsumeAndQuitThreadActivity extends Activity { 


    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     final ConsumeAndQuitThread consumeAndQuitThread = new ConsumeAndQuitThread(); 
     consumeAndQuitThread.start(); 

     for (int i = 0; i < 10; i++) { 
      Log.v("EATDEGUB","thread " + i + " started."); 

      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        for (int i = 0; i < 10; i++) { 
         Log.v("EATDEGUB","currentThread "+ Thread.currentThread().getId() + " : enqueueData is " + i); 
         SystemClock.sleep(new Random().nextInt(10)); 
         consumeAndQuitThread.enqueueData(i); 
        } 
       } 
      }).start(); 
     } 
    } 

    private static class ConsumeAndQuitThread extends Thread implements MessageQueue.IdleHandler { 

     private static final String THREAD_NAME = "ConsumeAndQuitThread"; 

     public Handler mConsumerHandler; 
     private boolean mIsFirstIdle = true; 

     public ConsumeAndQuitThread() { 
      super(THREAD_NAME); 
     } 

     @Override 
     public void run() { 
      Looper.prepare(); 

      mConsumerHandler = new Handler() { 
       @Override 
       public void handleMessage(Message msg) { 
        //mIsFirstIdle=true; 
        Log.v("EATDEGUB","handled message is " + msg.what); 
       } 
      }; 

      Looper.myQueue().addIdleHandler(this); 
      Looper.loop(); 
     } 


     @Override 
     public boolean queueIdle() { 
      Log.v("EATDEGUB","Thread " +currentThread().getId()); 

      if (mIsFirstIdle) { 
       mIsFirstIdle = false; 
       return true; 
      } 

      Log.v("EATDEGUB", "Thread " +currentThread().getId() + " is closed by calling quit()"); 


    mConsumerHandler.getLooper().quit(); 
     return false; 
    } 

    public void enqueueData(int i) { 
     mConsumerHandler.sendEmptyMessage(i); 
    } 
} 

}

LOG

02-24 13:54:41.490 thread 0 started. 
02-24 13:54:41.490 Thread 9590 
02-24 13:54:41.490 thread 1 started. 
02-24 13:54:41.490 thread 2 started. 
02-24 13:54:41.490 currentThread 9592 : enqueueData is 0 
02-24 13:54:41.490 currentThread 9591 : enqueueData is 0 
02-24 13:54:41.490 thread 3 started. 
02-24 13:54:41.490 currentThread 9593 : enqueueData is 0 
02-24 13:54:41.490 thread 4 started. 
02-24 13:54:41.490 currentThread 9594 : enqueueData is 0 
02-24 13:54:41.490 thread 5 started. 
02-24 13:54:41.490 currentThread 9595 : enqueueData is 0 
02-24 13:54:41.495 thread 6 started. 
02-24 13:54:41.495 currentThread 9596 : enqueueData is 0 
02-24 13:54:41.495 thread 7 started. 
02-24 13:54:41.495 thread 8 started. 
02-24 13:54:41.495 currentThread 9597 : enqueueData is 0 
02-24 13:54:41.495 currentThread 9598 : enqueueData is 0 
02-24 13:54:41.495 thread 9 started. 
02-24 13:54:41.495 currentThread 9599 : enqueueData is 0 
02-24 13:54:41.495 currentThread 9600 : enqueueData is 0 
02-24 13:54:41.495 currentThread 9598 : enqueueData is 1 
02-24 13:54:41.495 handled message is 0 
02-24 13:54:41.495 Thread 9590 

**02-24 13:54:41.495 Thread 9590 is closed by calling quit()** 

After this time, none of remaining message can be delivered. >> 

02-24 13:54:41.500 currentThread 9592 : enqueueData is 1 
02-24 13:54:41.500 currentThread 9591 : enqueueData is 1 
02-24 13:54:41.500 currentThread 9593 : enqueueData is 1 
02-24 13:54:41.505 currentThread 9597 : enqueueData is 1 
02-24 13:54:41.505 currentThread 9594 : enqueueData is 1 
02-24 13:54:41.505 currentThread 9595 : enqueueData is 1 
02-24 13:54:41.505 currentThread 9596 : enqueueData is 1 
02-24 13:54:41.510 currentThread 9600 : enqueueData is 1 
02-24 13:54:41.510 currentThread 9599 : enqueueData is 1 
02-24 13:54:41.510 currentThread 9592 : enqueueData is 2 
02-24 13:54:41.510 currentThread 9598 : enqueueData is 2 
02-24 13:54:41.515 currentThread 9593 : enqueueData is 2 
02-24 13:54:41.515 currentThread 9596 : enqueueData is 2 
02-24 13:54:41.515 currentThread 9591 : enqueueData is 2 
02-24 13:54:41.520 currentThread 9595 : enqueueData is 2 
02-24 13:54:41.520 currentThread 9600 : enqueueData is 2 
02-24 13:54:41.520 currentThread 9599 : enqueueData is 2 
02-24 13:54:41.520 currentThread 9594 : enqueueData is 2 
02-24 13:54:41.525 currentThread 9592 : enqueueData is 3 
02-24 13:54:41.525 currentThread 9597 : enqueueData is 2 
02-24 13:54:41.530 currentThread 9593 : enqueueData is 3 
02-24 13:54:41.530 currentThread 9591 : enqueueData is 3 
02-24 13:54:41.530 currentThread 9596 : enqueueData is 3 
02-24 13:54:41.530 currentThread 9598 : enqueueData is 3 
02-24 13:54:41.530 currentThread 9600 : enqueueData is 3 
02-24 13:54:41.535 currentThread 9595 : enqueueData is 3 
02-24 13:54:41.535 currentThread 9596 : enqueueData is 4 
02-24 13:54:41.535 currentThread 9594 : enqueueData is 3 
02-24 13:54:41.535 currentThread 9593 : enqueueData is 4 
02-24 13:54:41.535 currentThread 9591 : enqueueData is 4 
02-24 13:54:41.535 currentThread 9597 : enqueueData is 3 
02-24 13:54:41.540 currentThread 9592 : enqueueData is 4 
02-24 13:54:41.540 currentThread 9599 : enqueueData is 3 
02-24 13:54:41.540 currentThread 9599 : enqueueData is 4 
02-24 13:54:41.540 currentThread 9591 : enqueueData is 5 
02-24 13:54:41.545 currentThread 9593 : enqueueData is 5 
02-24 13:54:41.545 currentThread 9598 : enqueueData is 4 
02-24 13:54:41.545 currentThread 9598 : enqueueData is 5 
02-24 13:54:41.545 currentThread 9596 : enqueueData is 5 
02-24 13:54:41.550 currentThread 9594 : enqueueData is 4 
02-24 13:54:41.550 currentThread 9595 : enqueueData is 4 
02-24 13:54:41.550 currentThread 9600 : enqueueData is 4 
02-24 13:54:41.555 currentThread 9591 : enqueueData is 6 
02-24 13:54:41.565 currentThread 9597 : enqueueData is 4 
02-24 13:54:41.565 currentThread 9591 : enqueueData is 7 
02-24 13:54:41.565 currentThread 9599 : enqueueData is 5 
02-24 13:54:41.565 currentThread 9593 : enqueueData is 6 
02-24 13:54:41.565 currentThread 9596 : enqueueData is 6 
02-24 13:54:41.565 currentThread 9594 : enqueueData is 5 
02-24 13:54:41.565 currentThread 9598 : enqueueData is 6 
02-24 13:54:41.570 currentThread 9595 : enqueueData is 5 
02-24 13:54:41.570 currentThread 9600 : enqueueData is 5 
02-24 13:54:41.570 currentThread 9592 : enqueueData is 5 
02-24 13:54:41.575 currentThread 9599 : enqueueData is 6 
02-24 13:54:41.575 currentThread 9598 : enqueueData is 7 
02-24 13:54:41.575 currentThread 9591 : enqueueData is 8 
02-24 13:54:41.575 currentThread 9592 : enqueueData is 6 
02-24 13:54:41.575 currentThread 9593 : enqueueData is 7 
02-24 13:54:41.575 currentThread 9594 : enqueueData is 6 
02-24 13:54:41.575 currentThread 9600 : enqueueData is 6 
02-24 13:54:41.580 currentThread 9595 : enqueueData is 6 
02-24 13:54:41.580 currentThread 9592 : enqueueData is 7 
02-24 13:54:41.580 currentThread 9596 : enqueueData is 7 
02-24 13:54:41.580 currentThread 9599 : enqueueData is 7 
02-24 13:54:41.580 currentThread 9600 : enqueueData is 7 
02-24 13:54:41.585 currentThread 9597 : enqueueData is 5 
02-24 13:54:41.585 currentThread 9593 : enqueueData is 8 
02-24 13:54:41.585 currentThread 9598 : enqueueData is 8 
02-24 13:54:41.585 currentThread 9592 : enqueueData is 8 
02-24 13:54:41.585 currentThread 9591 : enqueueData is 9 
02-24 13:54:41.585 currentThread 9594 : enqueueData is 7 
02-24 13:54:41.585 currentThread 9593 : enqueueData is 9 
02-24 13:54:41.590 currentThread 9595 : enqueueData is 7 
02-24 13:54:41.590 currentThread 9596 : enqueueData is 8 
02-24 13:54:41.590 currentThread 9598 : enqueueData is 9 
02-24 13:54:41.595 currentThread 9600 : enqueueData is 8 
02-24 13:54:41.595 currentThread 9595 : enqueueData is 8 
02-24 13:54:41.600 currentThread 9599 : enqueueData is 8 
02-24 13:54:41.600 currentThread 9596 : enqueueData is 9 
02-24 13:54:41.600 currentThread 9594 : enqueueData is 8 
02-24 13:54:41.600 currentThread 9592 : enqueueData is 9 
02-24 13:54:41.600 currentThread 9597 : enqueueData is 6 
02-24 13:54:41.600 currentThread 9597 : enqueueData is 7 
02-24 13:54:41.605 currentThread 9600 : enqueueData is 9 
02-24 13:54:41.605 currentThread 9594 : enqueueData is 9 
02-24 13:54:41.605 currentThread 9595 : enqueueData is 9 
02-24 13:54:41.605 currentThread 9599 : enqueueData is 9 
02-24 13:54:41.610 currentThread 9597 : enqueueData is 8 
02-24 13:54:41.615 currentThread 9597 : enqueueData is 9 

回答

0

一年后)我读这本书,具有完全相同的问题。

我的猜测是,与睡眠行推出的空闲时间

SystemClock.sleep(new Random().nextInt(10)); 

杀死的处理程序,并返回false检测到的MessageQueue的空闲时间,第二次调用queueIdle。从现在开始,所有对sendMessage的调用都将在一个Handler和一个不再存在的Thread上完成,因此会出现错误。

这是我的猜测,所以我删除了行sleep并启动了应用程序:有时可以使用,但大多数情况下仍然存在错误。所以无论我的猜测是错误的,还是空闲时间都会因为不同的原因而发生。

相关问题