运行 简单后台任务的最简洁方法?
Most concise way to run a simple background task?
我已经看到至少五种模式,您可以通过这些模式在工作线程中为 运行 编写一些代码。最简单:
new Thread(new Runnable() {
public void run() {
//
}
}).start();
我们可以扩展AsyncTask
;我们有 AsyncTaskLoader
和其他 Loader
用于数据,Service
等等。
我认为其中每一个都有一些我不在这里讨论的优点。我想知道的是:运行 一个 简单 操作的最合适、简洁的方法是什么?
定义简单:
- 非常短的动作,<1s;
- 无需处理UI个元素;
- 一行命令之类的,所以用新的 class;
扩展 AsyncTask
看起来不合适
- 无需在
Activity
或 Fragment
中通知任务成功;
- 不需要显示进度;
- 只需要有某种
return
。
我一开始的想法是:
boolean myReturn;
new Thread(new Runnable() {
public void run() {
myReturn = myExtensiveTask();
}
}).start();
public boolean myExtensiveTask() { ... }
这是否正确(甚至可能)?应该怎么做?
最好的解决方案可能涉及一些库代码。
我在我当前的项目中实现了一些允许我编写如下方法的东西:
@QSchedule("0 * * * * ?")
public void runsEveryMinute()
{
System.out.println("It ran!");
}
我们现在到处都在使用这些。调度器在 QuartzScheduler 之上工作。我相信 spring 仅通过导入 Quartz 支持就允许像这样的语法。
如果您有创意,很多解决方案都可以这样运作。例如,如果您有一个构建菜单的 class,那么您可以抽象所有菜单构建语法并使用注释驱动它。我也这样做过。结构可能是这样的:
@MenuItem("File","Save")
public void fileSave() {
// This is executed when file save is selected
}
@MenuItem("File","Load")
public void fileLoad() {
// Executed when file load is seleclted
}
这些注释提供了构建整个菜单系统所需的所有信息,因此另一个 class 将遍历带注释的 class 并为其构建菜单。某处你有这样的代码:
Menu mainMenu = new MenuBuilder().buildMenu(MenuDefinition.class);
其中 MenuDefinition.class 包含如上的注释。这个解决方案最好的地方是什么? 100% 可重用——只需将其放入任何项目中,您就无需再次手动构建菜单(或按钮,或任何其他困扰您的冗余任务)。
我并不是说这会直接解决您的问题,我的意思是您可能想要编写一些基础设施代码以使您以后的调用更简单。注释是一种非常酷的方式来指示您想要 运行 的代码,因为 Java 具有如此丑陋的匿名内部 class 语法。
哦还有 Java 8 应该让你想做的事变得微不足道。在 Groovy 中(它的闭包很像 Java 8)你可以使用非常接近于此的东西:
new Thread() {
println "this will run in another thread"
}
(我不能保证这是准确的语法,但它真的很接近)
使用bolts
实用框架(Facebook和parse.com使用),就这么简单:
Task.callInBackground(new Callable<MyReturnType>() {
@Override
public MyReturnType call() {
MyReturnType obj = doWork();
return obj;
}
});
我已经看到至少五种模式,您可以通过这些模式在工作线程中为 运行 编写一些代码。最简单:
new Thread(new Runnable() {
public void run() {
//
}
}).start();
我们可以扩展AsyncTask
;我们有 AsyncTaskLoader
和其他 Loader
用于数据,Service
等等。
我认为其中每一个都有一些我不在这里讨论的优点。我想知道的是:运行 一个 简单 操作的最合适、简洁的方法是什么?
定义简单:
- 非常短的动作,<1s;
- 无需处理UI个元素;
- 一行命令之类的,所以用新的 class; 扩展
- 无需在
Activity
或Fragment
中通知任务成功; - 不需要显示进度;
- 只需要有某种
return
。
AsyncTask
看起来不合适
我一开始的想法是:
boolean myReturn;
new Thread(new Runnable() {
public void run() {
myReturn = myExtensiveTask();
}
}).start();
public boolean myExtensiveTask() { ... }
这是否正确(甚至可能)?应该怎么做?
最好的解决方案可能涉及一些库代码。
我在我当前的项目中实现了一些允许我编写如下方法的东西:
@QSchedule("0 * * * * ?")
public void runsEveryMinute()
{
System.out.println("It ran!");
}
我们现在到处都在使用这些。调度器在 QuartzScheduler 之上工作。我相信 spring 仅通过导入 Quartz 支持就允许像这样的语法。
如果您有创意,很多解决方案都可以这样运作。例如,如果您有一个构建菜单的 class,那么您可以抽象所有菜单构建语法并使用注释驱动它。我也这样做过。结构可能是这样的:
@MenuItem("File","Save")
public void fileSave() {
// This is executed when file save is selected
}
@MenuItem("File","Load")
public void fileLoad() {
// Executed when file load is seleclted
}
这些注释提供了构建整个菜单系统所需的所有信息,因此另一个 class 将遍历带注释的 class 并为其构建菜单。某处你有这样的代码:
Menu mainMenu = new MenuBuilder().buildMenu(MenuDefinition.class);
其中 MenuDefinition.class 包含如上的注释。这个解决方案最好的地方是什么? 100% 可重用——只需将其放入任何项目中,您就无需再次手动构建菜单(或按钮,或任何其他困扰您的冗余任务)。
我并不是说这会直接解决您的问题,我的意思是您可能想要编写一些基础设施代码以使您以后的调用更简单。注释是一种非常酷的方式来指示您想要 运行 的代码,因为 Java 具有如此丑陋的匿名内部 class 语法。
哦还有 Java 8 应该让你想做的事变得微不足道。在 Groovy 中(它的闭包很像 Java 8)你可以使用非常接近于此的东西:
new Thread() {
println "this will run in another thread"
}
(我不能保证这是准确的语法,但它真的很接近)
使用bolts
实用框架(Facebook和parse.com使用),就这么简单:
Task.callInBackground(new Callable<MyReturnType>() {
@Override
public MyReturnType call() {
MyReturnType obj = doWork();
return obj;
}
});