编程语言
首页 > 编程语言> > java – Handler.handleMessage未在测试中调用,但在应用程序中调用

java – Handler.handleMessage未在测试中调用,但在应用程序中调用

作者:互联网

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

如果我手动启动应用程序一切正常 – 处理程序在我的服务中收到消息.但在我的测试中,handleMessage()方法永远不会被调用.

如何修复我的测试以使handleMessage()方法有效?

谢谢!

服务:

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

}

测试:

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

App的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...

解决方法:

你的问题对我很有意思,所以我开始挖掘.

If I start the app manually everything works fine – messages are received by the Handler in my service.

当您使用mHandler = new ServiceHandler()在MyService的onCreate()方法中初始化mHandler时,Handler与当前执行的线程的消息队列相关联.来自队列的mHandler进程Messages,由Looper is looping处理.结果你可以看到“收到Hello World消息!”在日志中.

But in my test handleMessage() method is never get called.

当您测试服务时,其方法在InstrumentationThread上调用(请参阅调试器中的线程),其Looper为prepared但不循环,因此无法处理消息并且不会在日志中显示.

How can I fix my test to make handleMessage() method work?

我建议以下选项:

>将MyServiceTest绑定到调用MyService方法的线程.再为组件编写一个单元测试,然后将测试与MyServiceTest结合在一个常见的.java测试文件中.这将显示所需的logcat输出.
>在MyServiceTest中循环准备好的InstrumentationThread的Looper.您可以通过在MyServiceTest的testStartService()方法中添加Looper.loop()来实现:

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

注意:运行Looper将显示所需的logcat输出,但测试不会因为Looper.loop()无限期运行而停止,直到您调用Looper.quit().

标签:android-handler,android,java,android-service,android-testing
来源: https://codeday.me/bug/20190825/1714522.html