简体   繁体   English

如何从另一个线程调用线程的getHandler()方法?

[英]How can I call a thread's getHandler() method from another thread?

I'm running into the problem where one thread attempts to send a message to another thread's handler before its handler has been initialized. 我遇到了一个问题,即一个线程在初始化其处理程序之前尝试将消息发送到另一个线程的处理程序。 This asynchronous thread communication can easily lead to a nullpointerexception. 这种异步线程通信很容易导致nullpointerexception。

I'm trying to use the following code to fix this (a wait-notify algorithm) but I don't understand how to call getHandler() from my thread sending messages because I keep getting the "Non-static method cannot be called from a static context" error. 我正在尝试使用以下代码来解决此问题(一种等待通知算法),但是我不明白如何从发送消息的线程中调用getHandler(),因为我一直在获取“无法从静态上下文”错误。

The attempted fix to the message-receiveing thread's code: 尝试修复消息接收线程的代码:

public class LooperThread extends Thread {

    private static Handler mHandler;

    public void run() {
        Looper.prepare();

        synchronized (this) {
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
                    // process incoming messages here
                }
            };
            notifyAll();
        }

        Looper.loop();
    }

    public synchronized Handler getHandler() {
        while (mHandler == null) {
            try {
                wait();
            } catch (InterruptedException e) {
                //Ignore and try again.
            }
        }
        return mHandler;
    }
}

When I try the following code I keep getting the "non-static method cannot be called from a static context compiler error. 当我尝试以下代码时,我不断收到“无法从静态上下文编译器错误调用非静态方法的信息。

message-sending thread: 消息发送线程:

public class SenderThread extends thread{
    private static Handler senderHandler;

    public void run(){
        Looper.prepare();

        senderHandler = LooperThread.getHandler(); //This is where the error occurs!

        //do stuff
        senderHandler.msg(obj);
        Looper.loop();
    }
}

I know that I probably shouldn't try to initialize the sender thread's handler from within the run() method since it will be called repeatedly and will therefore be wasteful. 我知道我可能不应该尝试在run()方法中初始化发送方线程的处理程序,因为它将被重复调用,因此很浪费。 Where should I be calling LooperThread's getHandler() method from? 我应该在哪里调用LooperThread的getHandler()方法?

Background Info: 背景信息:

I used this question and one of the answers as a reference: How do I ensure another Thread's Handler is not null before calling it? 我以这个问题和一个答案作为参考: 如何确保另一个线程的处理程序在调用前不为null?

The meaning of the error Non-static method cannot be called from a static context is that you are trying to use a non-static (class member) in a static fashion (in your example, referring to LooperThread ). 错误的含义Non-static method cannot be called from a static context是因为您试图以静态方式使用非静态(类成员)(在您的示例中,引用LooperThread )。 The fix is typically to make the method at fault static, eg public static synchronized Handler getHandler() . 解决方法通常是使方法在故障时是静态的,例如, public static synchronized Handler getHandler()

In your case however you are using wait() which is a non-static method (and thus cannot be accessed from static context). 但是在您的情况下,您使用的是非静态方法wait() (因此无法从静态上下文中访问它)。 Instead you should change mHandler to be non-static state (thus there will be an mHandler per thread - which is what you want): private Handler mHandler; 相反,您应该将mHandler更改为非静态状态(因此每个线程都会有一个mHandler这就是您想要的): private Handler mHandler;

Inside of your SenderThread you will need to construct a LooperThread and then you can call its non-static getHandler() . SenderThread内部,您需要构造一个LooperThread ,然后可以调用其非静态的getHandler()

public class SenderThread extends Thread {
    private static Handler senderHandler;

    public void run(){
        Looper.prepare();

        LooperThread looperThread = new LooperThread();
        senderHandler = looperThread.getHandler(); // Should no longer error :-)

        //do stuff
        senderHandler.msg(obj);
        Looper.loop();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM