我在Android代码中启动一个可运行的线程,它在TimerTask中不断执行任务,直到调用stopTimerTask()。我想从主(UI)线程调用线程中的stopTimerTask()方法。我是这样开始的。
_member
请注意,我肯定需要从UIThread调用此方法。
答案 0 :(得分:0)
如果您的UI线程具有对Thread
或Runnable
对象的引用,那么它可以像调用任何其他对象的方法一样调用该对象的任何方法。该方法将在调用线程中运行。
另一方面,如果您希望某个方法在某个特定线程中运行,那么您必须安排该线程调用它。您可以这样做,例如,通过在目标线程使用的Runnable
对象上引发一个标志(您必须通过在Runnable
实现类上定义它来使该标志可用),并且具有实例该类定期测试该标志以确定是否调用相关方法。请务必正确同步此标志中的所有访问。
另外,我注意到示例代码中的匿名Runnable
实现类没有像您描述的那样执行任何操作。它只运行外部类的startTimer()
方法,然后完成。
答案 1 :(得分:0)
我使用处理程序/信使从一个调用GUI中方法的线程发送消息。我相信你可以改变我所做的并调用你的runnable中的方法。
在线程类中,您将定义以下内容:
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.getString(“COMMAND”) - >字符串命令是您为数据提供的密钥。你可以做任何你想做的事。
您的线程中需要以下实例变量:
private UpdaterHandler handler = new UpdaterHandler();
private Messenger messenger = new Messenger(handler);
现在你刚制作的messenger对象需要传回UI。所以在你的线程的构造函数中可能应该是这样的:
MyThreadClass(Context context){
((YourActivityClass)context).setMessenger(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(...)设置的。
现在,当您按下UI中的停止按钮时,它会创建一个新的消息对象,用命令填充它,然后将它提供给您从线程发送到UI的信使。 Messenger.send()会自动将其发送回正在运行的线程。在线程中,消息被解构,并根据其内容,您可以做任何您想做的事情。在这种情况下,您在线程本身内调用stopTimer方法。
在我自己的程序中,我在另一个方向上这样做,看看它是否有效会很有趣。显然你可以复制并粘贴一些代码,但我没有填写所有内容
- 你也可以打断刚停止的线程,但我认为这不是你想要的。
答案 2 :(得分:-1)
改变你的设计模式,问题可以解决,例如:
(defn world-view [data owner]
(let [cell (fn [data]
(om/component
(dom/td nil data)))
row (fn [data]
(om/component
(apply dom/tr nil (om/build-all cell data))))])
(om/component
(apply dom/table nil
(om/build-all row
(:world data)))))
}