Android消息处理程序未接收我发送的所有消息

4

我对Android编程及其相关的消息模型很陌生,但是基于我看到的所有代码示例,我得不到期望的结果。

我正在尝试从线程传递消息回UI线程,以便更新我的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

我无法在Nexus 7 Lollipop模拟器上运行这个完全相同的代码进行复现。 - corsair992
有趣 - 我应该提到我正在 Nexus 5 5.0.1 模拟器上运行。让我在 7 上尝试一下。你在模拟哪个操作系统版本?(我在 API 级别 21,准确地说) - Sean Colbath
我正在使用Lollipop 5.0.0上的Genymotion模拟器。 - corsair992
好的,我想我已经找到了,@corsair992,你给了我线索。我将添加一篇文章来解释我认为的情况——如果你也这样做,我会给你胜利的功劳。 - Sean Colbath
1个回答

0

由@corsair992发现的解决方案。

上面的代码在HAXM Intel模拟器、Nexus-5、API Level 21、x86_64上运行(不知道64位是否相关,但暂时假设它是)。我正在使用Android Studio进行开发。

受@corsair992的评论启发,我在一个Nexus-7 API Level 21 arm模拟器中运行了代码。代码表现如你所预期的那样,就像corsair看到的那样。

接下来,我创建了一个具有相同规格的Nexus-5 ARM模拟器。代码正确运行(没有丢失消息)。

回到HAXM Intel模拟器:有错误的代码。

所以,我现在的问题是:HAXM模拟器是否已知存在错误?有人能在那个模拟器上尝试吗?


好的,我会在x86 ATOM系统映像中尝试这个。我已经下载了带有Google API的版本,但它非常不稳定,启动器经常崩溃。我会看看在标准版本上是否运气更好。 - corsair992
目前为止的最后一次跟进 - 问题似乎与_x64模拟器有关。看起来纯x86可以正常工作。 - Sean Colbath
嗯,模拟器甚至无法完全初始化,所以肯定有漏洞 :) - corsair992
除了模拟器,我在真实设备(Nexus 5)上也看到了这种行为。仍然不知道如何解决它。 - Alex Dmitriev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接