Handler.handleMessage在测试中没有被调用,但在应用程序中被调用

2023-12-10

我有一项在单独进程中运行的服务。该服务生成一个新线程onCreate()方法。该线程将消息发送回服务。

如果我手动启动应用程序,一切都会正常 - 消息会被接收Handler在我的服务中。但在我的测试中handleMessage()方法永远不会被调用。

我该如何修复我的测试handleMessage()方法工作?

Thanks!

Service:

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);
    }
}

应用程序的 logcat 输出(handleMessage()叫做):

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

测试的 logcat 输出(handleMessage()不被调用):

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

你的问题对我来说很有趣,所以我开始挖掘.

如果我手动启动应用程序,一切都会正常 - 消息会被接收Handler在我的服务中。

当你初始化时mHandler in the MyService's onCreate()方法与mHandler = new ServiceHandler(), the Handler与当前执行线程的消息队列相关联。mHandler过程Messages从队列中依次处理Looper which 正在循环。结果你可以看到“收到Hello World消息!”在日志中。

但在我的测试中handleMessage()方法永远不会被调用。

当您测试服务时,会调用其方法InstrumentationThread(参见中的线程Debugger) whose Looper is prepared but 不循环,因此消息无法处理并且不会显示在日志中。

如何修复我的测试以使handleMessage() 方法起作用?

我建议以下选项:

  • Tie MyServiceTest到其上的线程MyService的方法称为。再写一篇unit test对于组件,然后将测试与MyServiceTest在一个共同点.java测试文件。这将显示所需的logcat output.
  • 循环准备好的Looper of InstrumentationThread in MyServiceTest。您可以通过添加来做到这一点Looper.loop() in the testStartService()的方法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);
    }
    

    Note: 运行Looper将显示所需的logcat输出,但测试不会停止,因为Looper.loop()无限期运行直到你打电话Looper.quit().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Handler.handleMessage在测试中没有被调用,但在应用程序中被调用 的相关文章

随机推荐