【问题标题】:How can I call a thread's getHandler() method from another thread?如何从另一个线程调用线程的 getHandler() 方法?
【发布时间】:2015-12-11 15:08:33
【问题描述】:

我遇到了一个问题,即一个线程在其处理程序初始化之前尝试将消息发送到另一个线程的处理程序。这种异步线程通信很容易导致空指针异常。

我正在尝试使用以下代码来解决此问题(等待通知算法),但我不明白如何从发送消息的线程中调用 getHandler(),因为我不断收到“非静态方法不能从静态上下文中调用”错误。

尝试修复消息接收线程的代码:

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

当我尝试以下代码时,我不断收到“无法从静态上下文编译器错误中调用非静态方法。

消息发送线程:

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

我知道我可能不应该尝试在 run() 方法中初始化发送者线程的处理程序,因为它会被重复调用,因此会很浪费。 我应该从哪里调用 LooperThread 的 getHandler() 方法?

背景信息:

我使用了这个问题和其中一个答案作为参考:How do I ensure another Thread's Handler is not null before calling it?

【问题讨论】:

    标签: java android multithreading handler


    【解决方案1】:

    错误Non-static method cannot be called from a static context 的含义是您试图以静态方式使用非静态(类成员)(在您的示例中,指的是LooperThread)。修复通常是使发生故障的方法静态,例如public static synchronized Handler getHandler().

    但是,在您的情况下,您使用的是wait(),这是一种非静态方法(因此无法从静态上下文中访问)。相反,您应该将 mHandler 更改为非静态状态(因此会有一个 mHandler 每个线程 - 这就是您想要的):private Handler mHandler;

    在您的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();
        }
    }
    

    【讨论】:

    • 谢谢。不过我很好奇:有没有办法在不从 SenderThread 构造 LooperThread 的情况下完成此功能?目前,我从主线程(在 Android 设备上称为“UI 线程”)创建两个线程,如果可能的话,我希望保持这种状态。
    猜你喜欢
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    相关资源
    最近更新 更多