我正在尝试创建一个简单的UI来启动selenium测试,该测试能够启动后台线程,当按下“开始”按钮时启动浏览器并停止线程并在按下“停止”按钮时将其关闭。 不幸的是,当我在启动后单击停止时,它不起作用。如果我让它完成我无法重启线程。我将如何进行更新,以便我可以提交一个可以通过停止按钮停止的新线程。
DatabaseReference mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
Query query = mFirebaseDatabaseReference.child("users").orderByChild("name").equalTo("Fazal");
query.addValueEventListener(valueEventListener);
ValueEventListener valueEventListener = new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot postSnapshot : dataSnapshot.getChildren())
{
//TODO get the data here
User user = dataSnapshot.getValue(User.class);
}
}
@Override
public void onCancelled(DatabaseError databaseError)
{
}
};
答案 0 :(得分:1)
与FutureTask一样,Task是一次性类,无法重用。请参阅服务以获取可重复使用的工作人员。
所以你必须为每次运行创建新任务。所以我在Main中添加了task作为字段:
Stage window;
GridPane grid;
Task<Void> task;
然后在单击开始按钮时创建任务:
buttonStart.setOnAction(new EventHandler<ActionEvent>() {
/*
* Start Button Clicked
*/
@Override
public void handle(ActionEvent event) {
if(task != null) {
System.out.println("Task already running");
return;
}
task = new Task<Void>() {
@Override
protected Void call() {
new VisitPage().start(this, URLTextField.getText());
;
return null;
}
};
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
});
点击停止按钮,你必须取消任务:
buttonStop.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if(task == null) {
System.out.println("Task not running");
return;
}
System.out.println("Stop Pressed");
task.cancel();
task = null;
}
});
这不会做任何事情,因为你有责任在取消任务时结束任务,并且你没有结束你的无限循环。 所以你的VisitPage应该是这样的(我跳过了测试细节,因为我没有在classpath上使用它们):
public class VisitPage {
public void start(Task<Void> task, String URL) {
while (!task.isCancelled()) {
System.out.println("Running test");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Test run ended");
}
System.out.println("Canceling...");
System.out.println("Stop Pressed");
return;
}
}
一些小问题:
技术上task.cancel()
有时会结束你的线程,如果你的线程处于休眠状态时你不会捕获被抛出的InterruptedException
。
我不确定你的代码是如何编译的,但我必须将一些变量最终化,以便它们可以在处理程序中使用:(没关系,从Java SE 8局部变量可以有效地最终)
final TextField URLTextField = new TextField();
//...
final Task<Void> task = new Task<Void>(){
//...
我会将创建的线程定义为守护进程,以便在不停止测试的情况下关闭UI时它不会继续运行:
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
我还将Start
方法重命名为start