【发布时间】:2014-12-02 08:52:27
【问题描述】:
在我目前正在处理的项目中,有大量缓存在主线程上完成,这使得应用程序滞后。我的计划是制作这些的异步变体,但仍然保持同步调用以便在 asyncTasks 中组合时更容易链接。我的问题是我想以某种直观的方式防止在 GUI 线程中使用缓存功能。有任何想法吗?可能吗?是否可以使用注释标记方法以防止在 GUI 线程上调用它?
【问题讨论】:
标签: java android multithreading annotations
在我目前正在处理的项目中,有大量缓存在主线程上完成,这使得应用程序滞后。我的计划是制作这些的异步变体,但仍然保持同步调用以便在 asyncTasks 中组合时更容易链接。我的问题是我想以某种直观的方式防止在 GUI 线程中使用缓存功能。有任何想法吗?可能吗?是否可以使用注释标记方法以防止在 GUI 线程上调用它?
【问题讨论】:
标签: java android multithreading annotations
http://androidannotations.org/ 提供了一个库,它利用注释的使用来处理这个问题。它们具有 @UiThread 和 @Background 等注释,基本上取代了分别使用 runOnUiThread() 和 AsyncTask 的需要。
如果您有兴趣,这里有一个paper 讨论一个类似的系统来处理来自非 UI 线程的 UI 线程操作的阻塞。
【讨论】:
据我所知没有这种可能性。
也许您可以尝试使用 Android.Handlers 使用“状态机”
结帐
Google Android Communication with UI Thread using Handlers
My favorite ---> Very clean and tidy article about Handlers!
也值得在谷歌上搜索“使用处理程序的 android 状态机”!这样我就找到了我的问题 J 的解决方案。
希望你能找到一些有用的信息。
【讨论】:
我不知道有任何注释,但最好让它异步。就我个人而言,我并不真正关心 AsyncTask,因为我认为代码变得非常混乱,尤其是当您需要将调用链接在一起等时,就像您提到的那样。
AsyncTask 的替代品提供更简单的链接、错误处理等。例如,您可以使用 Promise。 JQ 是一个用于 Java7/Android 的 Promise 库,它基本上是 JavaScript Promises/A+ 规范的 Java 端口。 Promise 基本上是 Future 的扩展,带有用于使用回调观察完成的可链接方法。
作为一个例子(取自 JQ 文档),想象一下使用慢速阻塞方法 foo、bar 和 baz 的同步代码:
try {
int x = foo();
int y = bar(x);
return baz(y);
} catch (Exception e) {
return -1;
} finally {
// Always called
}
可能变成
return foo().then(x -> {
return bar(x);
}).then(y -> {
return baz(y);
}).fail(e -> {
return Value.wrap(-1);
}).fin({
// Always called
});
(用于减少示例冗长的 lambda 简写,实际上你会写 then(new OnFulfilledCallback() {...}) 等,但 Android Studio 会让这变得非常简单,并且在某种程度上也会自动折叠 - 或者你可以使用 Retrolambda 来获取 Java8-使用 Java7 的样式 lambda 语法。)
方法foo、bar 和baz 的实现将返回Promise 并在工作线程上执行实际工作。您可以自己实现这一点,或者使用JQ 提供的工具来轻松创建承诺,并将相关的工作卸载到工作线程:
private Promise<Integer> foo() {
return JQ.defer(() -> {
int result = 42;
// do some heavy processing...
return result;
});
}
注意JQ 还提供了有用的utilities 用于同步多个并行操作、为长时间运行的操作添加超时等。
免责声明:由于我是JQ的作者,所以有些无耻的宣传。 ;)
【讨论】: