Android线程处理程序未接收到消息。

3

我有一个线程处理程序接收消息的问题。在我实现此模式的所有其他线程中,一切都正常。这是我的代码:

启动线程

InternalScoresThread t = new InternalScoresThread(
    this.game.getApplicationContext(),
    this.map.fileName, this.map.getCurrentTime(),
    new Handler() {

        @Override
        public void handleMessage(Message msg) {

            Log.d("DEBUG", "message received");

            if (msg.getData().getBoolean("record")) {

                Player.this.showtRecordMessage();

            } else {

                Player.this.showtFinishMessage();
            }

            Player.this.showTimeMessage();
            Player.this.showRestartMessage();
        }
});

t.start();

线程类

public class InternalScoresThread extends Thread {

    private Handler handler;
    private String map;
    private float time;
    private Context context;

    public InternalScoresThread(Context context, String map, float time, Handler handler) {

        this.context = context;
        this.handler = handler;
        this.map = map;
        this.time = time;
    }

    @Override
    public void run() {         

        Log.d("DEBUG", "thread started");

        Database db = Database.getInstance(this.context);
        float bestTime = db.getBestTime(this.map);
        db.addRace(this.map, this.time);

        Log.d("DEBUG", "race added");

        Message msg = new Message();
        Bundle b = new Bundle();
        b.putBoolean("record", this.time < bestTime || bestTime == 0);
        msg.setData(b);
        this.handler.sendMessage(msg);

        Log.d("DEBUG", "message sent");
    }
}

“线程已启动”,“竞赛已添加”和“消息已发送”日志出现在logcat中,但是处理程序中的“消息已接收”日志没有出现。

2个回答

6

我不知道为什么,但是使用dispatchMessage()而不是sendMessage()解决了这个问题...


你有其他解释为什么会发生这种情况吗?我大约有50%的时间遇到这个问题。 - JuJoDi
2
dispatchMessage() 直接在同一线程中调用 handleMessage(),因此它并不能真正解决线程间通信的问题。 - Memetic
1
@Memetic所说的是正确的。如果你计划在接收到消息时更新任何UI,使用“dispatchMessage(Message)”会立即抛出错误。你可以尝试使用“sendMessageAtFrontOfQueue(Message)”。在我的情况下,我连续调用了两个方法,这两个方法都使用了消息传递。使用一个倒计时器将第二个方法的调用延迟3秒后解决了问题。 - Wrichik Basu

2

我知道这是一个老问题,但是Google。

问题在于你在UI线程中创建了Handler。然后它会在该线程上接收消息。你需要在新的线程中创建Handler:

public void run() {
    Log.d("DEBUG", "creating Handler in thread " + Thread.currentThread().getId());
    Looper.prepare();
    handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.d("DEBUG", "message received");
        }
    };
    Looper.loop();

那为什么是个问题呢?他想要在UI线程中处理程序,因为他需要更新UI。 - Greg Ennis
2
也许我的回答可以措辞得更好一些。关键是他在同一个线程上发送和接收消息。处理程序并不在新线程上监听,而是在创建它的旧线程上(稍后会发送消息)。我相当确定他试图向新线程发送消息。 - Memetic

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