Android 我无法从处理程序创建UI元素';s handleMessage呼叫 更新1

Android 我无法从处理程序创建UI元素';s handleMessage呼叫 更新1,android,Android,我做了更多的调试,发现构造函数是从主UI线程运行的,而handleMessage(Message)方法是在我创建的线程上运行的,这与我对处理程序的理解完全矛盾 问题 我已经在安卓上工作了一段时间,我遇到了一个似乎没有记录的问题。我的代码没有做任何特殊的事情。我似乎无法让我的应用程序从处理程序的handleMessage方法创建任何UI元素,例如警报对话框和Toast消息 此外,我还得到一个“线程未调用Looper.prepare()”异常。但是,我认为我甚至不需要调用Looper.prepare

我做了更多的调试,发现构造函数是从主UI线程运行的,而handleMessage(Message)方法是在我创建的线程上运行的,这与我对处理程序的理解完全矛盾

问题 我已经在安卓上工作了一段时间,我遇到了一个似乎没有记录的问题。我的代码没有做任何特殊的事情。我似乎无法让我的应用程序从处理程序的handleMessage方法创建任何UI元素,例如警报对话框和Toast消息

此外,我还得到一个“线程未调用Looper.prepare()”异常。但是,我认为我甚至不需要调用Looper.prepare(),因为我没有在Thread对象内部创建处理程序。我在主UI线程中调用构造函数,然后将其传递给新线程的构造函数

我所期望的 我应该会看到一个祝酒词以及一个警告对话框

到底发生了什么 没什么。我在应用程序上运行了调试器,发现JVM确实启动了线程。调用run方法并调度消息。处理程序处理该方法,我运行了创建AlertDialog和Toast消息的所有方法,但没有显示任何内容

我已经在运行4.2的模拟器上运行了这个应用程序,我朋友的三星Galaxy S3运行了4.0.4,我自己的Droid X2运行了2.3.5

程序流程
  • 我在UI线程上创建了一个处理程序
  • 我创建并启动一个线程,该线程将向处理程序发送消息
  • 处理程序将处理该消息
  • 源代码


    问题是我调用了dispatchMessage(Message),它在当前线程上即时执行。我应该使用sendMessage(Message),它将给定的消息排队到最初创建处理程序的原始线程的消息队列中。

    您应该使用
    发送稍后将由handleMessage处理的消息。

    如果您刚才调用了
    handler.dispatchMessage()
    ,单击
    onClick
    会怎么样?或者,您可以调用
    handler.post(Runnable r)
    ,Runnable将使
    Toast
    或显示
    对话框。另外,请使用
    Log.d()
    而不是
    System.out.println()
    。这是我的应用程序的一个极其简化的版本,但我仍然遇到一个问题,即处理程序的handleMessage方法正在Main以外的其他线程中执行。例如,我的测试显示它在“pool-2-thread-1”上运行。在我的实际应用程序中,我正在创建一个自定义侦听器,该侦听器在后台使用处理程序来处理所有异步回调。问题是,由于某种原因,我无法将处理程序传递给我的线程并让它分派消息。也许我不了解自己程序的流程,或者我不了解处理程序是如何工作的。
    package com.nguyenmp.ErrorTest;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MyActivity extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            //Init the UI
            setContentView(R.layout.main);
    
            //Create a new handler, passing it the current activity context
            final Handler handler = new MyHandler(MyActivity.this);
    
            //Bind a listener to the button on the UI
            View view = findViewById(R.id.button);
            view.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    //Start a new thread that will send a message to that handler
                    new MyThread(handler).start();
                }
    
            });
        }
    
        private class MyThread extends Thread {
            private final Handler mHandler;
    
            MyThread(Handler handler) {
                mHandler = handler;
            }
    
            @Override
            public void run() {
                //Dispatch message to UI thread asynchronously
                Looper.prepare();
                mHandler.dispatchMessage(mHandler.obtainMessage());
            }
        }
    
        private class MyHandler extends Handler {
            private final Context mContext;
    
            MyHandler(Context context) {
                mContext = context;
            }
    
            @Override
            public void handleMessage(Message msg) {
                //Show that we got the message
                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                builder.setTitle("HelloWorld");
                builder.setMessage("It worked!");
                builder.show();
    
                //Another variant of showing that we got the message
                Toast.makeText(mContext, "Message Received", Toast.LENGTH_SHORT).show();
    
                System.out.println("Yeah");
            }
        }
    }