java中如何从主线程调用线程的方法

java中如何从主线程调用线程的方法,java,android,multithreading,Java,Android,Multithreading,我在我的Android代码中启动一个可运行的线程,它在TimerTask中连续执行一个任务,直到调用stopTimerTask为止。我想从主UI线程调用线程中的stopTimerTask方法。我是这样开始的 public void test() { new Thread(runWaitResponseProcedure).start(); } Runnable runWaitResponseProcedure = new Runnable() {

我在我的Android代码中启动一个可运行的线程,它在TimerTask中连续执行一个任务,直到调用stopTimerTask为止。我想从主UI线程调用线程中的stopTimerTask方法。我是这样开始的

 public void test() {
        new Thread(runWaitResponseProcedure).start();
    }

    Runnable runWaitResponseProcedure = new Runnable() {
        startTimer();
    }

请注意,我确实需要从UIThread调用此方法

如果UI线程引用了线程或可运行对象,那么它可以调用该对象的任何方法,就像调用任何其他对象的方法一样。该方法将在调用线程中运行

另一方面,如果希望在某个特定线程中运行方法,则必须安排该线程调用该方法。例如,您可以在目标线程正在使用的可运行对象上提升一个标志,您必须在可运行实现类上定义该标志,并让该类的实例定期测试该标志,以确定是否调用有问题的方法,从而使该标志可用。确保正确同步来自此标志的所有访问


另一方面,我注意到示例代码中的匿名Runnable实现类与您描述的完全不同。它只需运行外部类的startTimer方法一次,然后完成。

更改您的设计模式,就可以解决问题,例如:

 public class RunTimerManager implements Runnable {

public void startTimer() {

}

public void stopTimer() {

}

public void test() {

    new Thread(this).start();

    try {
        wait(10000);
    } catch (Exception e) {
        e.printStackTrace();
    }
    stopTimer();

}

@Override
public void run() {
    // ........
}

}

我使用处理程序/信使从调用GUI中方法的线程发送消息。我相信您可以逆转我所做的,并在runnable中调用方法

在thread类中,您将定义以下内容:

public class UpdaterHandler extends Handler{
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){
            case 1:
                Bundle data = msg.getData();
                String update = data.getString("COMMAND");
                if(update.equals("STOP"){
                    stopTimer();
                break;

            default:
                super.handleMessage(msg);
                break;
        }

    }
}
注意:msg.what包含一个整数,可以像主GUI中的标记一样设置该整数。可能会有其他消息通过,但int 1表示这是您发送的消息。data.getStringCOMMAND->string命令是您为数据提供的键。你想做什么就做什么

线程中需要以下实例变量:

private UpdaterHandler handler = new UpdaterHandler();
private Messenger messenger = new Messenger(handler);
现在,您刚刚创建的messenger对象需要传递回UI。因此,在线程的构造函数中,可能应该是:

MyThreadClass(Context context){
((YourActivityClass)context).setMessenger(messenger)
....
}
这将在UI中为您提供messenger

现在在您的UI中:

Message message;

stopTimerButton.setOnclickListener ..... {
      message = Message.obtain();
      bundle = new Bundle();
      bundle.putString("COMMAND", "STOP");
      message.setData(bundle);
      message.what = 1;
      messenger.send(message);
}
注意,此处的messenger是使用setMessenger设置的messenger。。。你从线程中调用的

现在,当您按下UI中的停止按钮时,它会创建一个新的消息对象,用命令填充它,然后将其提供给messenger,您可以从线程将其发送到UI。Messenger.send将自动将其发送回正在运行的线程。在线程中,消息被解构,根据它的内容,你可以做任何你想做的事情。在这种情况下,可以在线程本身内调用stopTimer方法

在我自己的程序中,我从另一个方向做了这件事,看看它是否有效会很有趣。很明显,你可以复制和粘贴一些代码,但我没有填写所有内容

-你也可以中断线程,这将停止它,但我不认为这是你想要的