2015-01-11 111 views
2

我對Android編程及其關聯的消息傳遞模型非常陌生,但根據所見的所有代碼示例,我沒有得到預期的結果。Android消息處理程序未收到我發送的所有消息

我想將消息從線程傳遞迴UI線程,以便我可以更新我的UI。下面的示例代碼試圖抽象出問題。我的用戶界面中有一個處理程序設置爲接收消息,而一個線程類發送帶有計數器的消息,休眠一秒鐘,遞增計數器併發送另一個消息。問題是我看到發送者線程發送從未收到的消息。有時他們是 - 並且需要長時間的信息。然後一堆被送去並丟失。然後他們再次收到。

上一個問題意味着我應該使用dispatchMessage而不是sendMessage - 這實際上可以工作(!),但顯然不是適當的方法來做事情,並且sendMessage應該工作。

那麼,我錯過了什麼是令人難以置信的明顯的東西? :-)

這裏的活動:

package org.foo.testapp; 

import android.os.Handler; 
import android.os.Looper; 
import android.os.Message; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 

public class MainActivity extends ActionBarActivity { 

    Handler mHandler; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mHandler = new Handler(Looper.getMainLooper()) { 
      @Override 
      public void handleMessage(Message inputMessage) { 
       System.out.println("HANDLE: " + inputMessage.obj); 
       // Looper.loop(); This doesn't seem to matter either way 
      } 
     }; 
    } 

    public void startEverything(View v) { 
     System.out.println("Button clicked"); 

     TestMessage tm = new TestMessage(mHandler); 
     Thread tmthread = new Thread(tm); 
     tmthread.start(); 
    } 
} 

這裏的線程發送消息:

package org.foo.testapp; 

import android.os.Handler; 
import android.os.Message; 

public class TestMessage implements Runnable { Handler mHandler; 
    int foo; 

    TestMessage(Handler inputHandler) { 
     mHandler = inputHandler; 
     foo = 0; 
    } 

    public void run() { 
     while(true) { 
      foo = foo + 1; 
      Message msg = mHandler.obtainMessage(); 
      msg.obj = "SENDING " + foo; 
      System.out.println("SENDING " + foo); 
      //mHandler.sendMessage(msg); this loses messages 
      if(!mHandler.sendMessage(msg)) { 
       System.out.println("Error sending!"); 
      } 
      //mHandler.dispatchMessage(msg); 
      try { 
       Thread.sleep(1000); 
      } catch(InterruptedException ex) { 
       Thread.currentThread().interrupt(); 
      } 
     } 
    } 
} 

..和這裏的輸出類型,我得到當我使用的sendMessage(精確的輸出而異) 。

Button clicked 
SENDING 1 
HANDLE: SENDING 1 
SENDING 2 
HANDLE: SENDING 2 
SENDING 3 
HANDLE: SENDING 3 
SENDING 4 
HANDLE: SENDING 4 
SENDING 5 
SENDING 6 
SENDING 7 
SENDING 8 
SENDING 9 
SENDING 10 
SENDING 11 
SENDING 12 
SENDING 13 
SENDING 14 
SENDING 15 
SENDING 16 
SENDING 17 
SENDING 18 
SENDING 19 
SENDING 20 
+0

我無法在Nexus 7 Lollipop仿真器上運行此確切代碼來重現此操作。 – corsair992

+0

有趣的 - 我應該提到我在Nexus 5 5.0.1模擬器上運行。讓我試試7.你在模擬什麼操作系統級別? (準確的說,我在API級別21) –

+0

我在棒棒堂上使用Genymotion模擬器5.0.0 – corsair992

回答

0

由於@ corsair992發現的解決方案。

上述代碼運行在HAXM英特爾仿真器Nexus-5,API Level 21,x86_64(不知道64位是否相關,但讓我們暫時假設它)。我正在開發Android Studio。

由@ corsair992的評論提醒,我在Nexus-7 API Level 21 arm模擬器中運行代碼。代碼的行爲和你期望的一樣,正如海盜看到的一樣。

接下來,我創建了具有相同規格的Nexus-5 ARM仿真器。代碼正確運行(沒有消息丟失)。

返回HAXM英特爾仿真器:buggy代碼。

所以,我猜我現在的問題是:是HAXM模擬器已知是越野車?有人可以試用該仿真器嗎?

+0

好的,我會在x86 ATOM系統映像中嘗試這個。我已經下載了Google API的版本,但它非常麻煩,並且發射器不斷崩潰。我會看看我是否對標準版本有更好的運氣。 – corsair992

+0

最後的後續行動 - 這個問題畢竟似乎與_x64模擬器有關。它看起來像直的x86工作正常。 –

+0

那麼,模擬器甚至沒有完全爲我初始化,所以它絕對是越野車:) – corsair992

相關問題