Handler.handleMessage non viene chiamato nel test, ma viene chiamato nell'applicazione

Ho un servizio che viene eseguito in un process separato. Il servizio genera un nuovo thread nel metodo onCreate() . Questo thread invia i messaggi al servizio.

Se iniziano l'applicazione manualmente tutto funziona bene – i messaggi vengono ricevuti dal Handler nel mio servizio. Ma nel mio metodo handleMessage() metodo non viene mai chiamato.

  • Scaricare i file e memorizzarli localmente con Phonegap / jQuery Mobile Android e iOS Apps
  • IOException each volta che cerco di caricare qualcosa all'emulatore android
  • C'è qualche motivo per utilizzare Google GCM vs Apple messaging per le notifiche push?
  • Recupera le informazioni sulle torri di cella
  • Come ridimensionare una visualizzazione personalizzata in modo programmato?
  • Fornire la corretta interpretazione della percentuale di trasformazione CSS3 su Android
  • Come posso risolvere il mio test per eseguire il metodo handleMessage() ?

    Grazie!

    Servizio:

     public class MyService extends Service { private ServiceHandler mHandler; private final int MSG_HELLO_WORLD = 1; private final String TAG = getClass().getSimpleName(); @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return null; } @Override public void onCreate() { Log.d(TAG, "MyService.onCreate"); super.onCreate(); mHandler = new ServiceHandler(); new Thread(new Runnable() { @Override public void run() { Log.d(TAG, "Thread: run()"); while (true) { try { Log.d(TAG, "sleeping..."); Thread.sleep(3000); } catch (InterruptedException e) { Log.d(TAG, "Thread was interrupted."); break; } Log.d(TAG, "sending message..."); Message msg = Message.obtain(mHandler, MSG_HELLO_WORLD); msg.sendToTarget(); } } }).start(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "MyService.onStartCommand"); return START_REDELIVER_INTENT; } private class ServiceHandler extends Handler { @Override public void handleMessage(Message msg) { Log.d(TAG, "ServiceHandler.handleMessage"); if (msg.what == MSG_HELLO_WORLD) { Log.d(TAG, "Hello World message received!"); } } } } 

    Test:

     public class MyServiceTest extends ServiceTestCase<MyService> { private static final String TAG = MyService.class.getSimpleName(); public MyServiceTest() { super(MyService.class); } public void setUp() throws Exception { super.setUp(); } public void testStartService() throws Exception { Intent startServiceIntent = new Intent(getContext(), MyService.class); startService(startServiceIntent); MyService myService = getService(); assertNotNull(myService); // give the service some time to send messages Thread.sleep(10000); } } 

    L'output di handleMessage() App ( handleMessage() viene chiamato):

     MyService.onCreate MyService.onStartCommand Thread: run() sleeping... sending message... sleeping... ServiceHandler.handleMessage Hello World message received! sending message... sleeping... 

    L'output del handleMessage() del test ( handleMessage() non viene chiamato):

     MyService.onCreate MyService.onStartCommand Thread: run() sleeping... sending message... sleeping... sending message... sleeping... sending message... sleeping... 

  • Android - Ruotare un ImageView con il dito muove altre viste in giro
  • Come get il path della miniatura video e non la bitmap
  • Come posso usare il model di codice in android quando creo il progetto dalla row di command?
  • Linea generata dynamicmente con efficacia luminosa
  • Android Studio non è riuscito a trovare una versione corrispondente a com.android.support:appcompat-v7:+
  • Come get il layout grafico di nuovo in Eclipse per l'applicazione di applicazioni Android?
  • One Solution collect form web for “Handler.handleMessage non viene chiamato nel test, ma viene chiamato nell'applicazione”

    La tua domanda mi è sembrata interessante, quindi ho iniziato a scavare .

    Se iniziano l'applicazione manualmente tutto funziona bene – i messaggi vengono ricevuti dal Handler nel mio servizio.

    Quando si inizializza mHandler nel metodo onCreate() di mHandler = new ServiceHandler() con mHandler = new ServiceHandler() , Handler viene associato alla coda dei messaggi del thread attualmente eseguito. Messages mHandler Messages dalla coda che a sua volta viene gestita da Looper che è looping . Come risultato puoi vedere il messaggio "Hello World ricevuto!" nei registri.

    Ma nel mio metodo handleMessage() metodo non viene mai chiamato.

    Quando si prova il servizio i suoi methods sono chiamati su InstrumentationThread (vedere i thread in Debugger ) il cui Looper è preparato, ma non looping , quindi i messaggi non possono essere gestiti e non vengono visualizzati nei registri.

    Come posso risolvere il mio test per eseguire il metodo handleMessage ()?

    Suggerisco le seguenti opzioni:

    • MyServiceTest al thread su cui si MyService i methods di MyService . Scrivere un altro unit test per il componente e quindi combinare il test con MyServiceTest in un file di prova comune .java . Questo mostrerà l'output logcat desiderato.
    • MyServiceTest il Looper preparato di InstrumentationThread in MyServiceTest . È ansible farlo aggiungendo Looper.loop() nel metodo testStartService() di MyServiceTest :

       public void testStartService() throws Exception { Intent startServiceIntent = new Intent(getContext(), MyService.class); startService(startServiceIntent); MyService myService = getService(); assertNotNull(myService); // Run the Looper (this call is to be added) Looper.loop(); Thread.sleep(10000); } 

      Nota : l'esecuzione del Looper mostrerà l'output di logcat desiderato, ma il test non si arresta a causa di Looper.loop() esecuzione indefinitamente fino a quando non chiamerai Looper.quit() .

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.