考虑到以下情况:

我希望这些线程执行这些方法:
OnClick (按系统):uiOnRefresh (1):uiReadDb (2):工人SetData(3):ui我可以通过ReadDb异步和_await_ing来实现这一点,但是它会冻结UI线程。
您能想到一种不涉及实现Interactors、AsyncTask等的方法吗?
谢谢。
编辑
我正在寻找一个优雅的解决方案,请避免像new Handler (Looper.getMainLooper()).post(...)、RunOnUiThread这样的包装器出现在View的每个方法中等等。
最简单的方法是使用taskt和await
async OnRefresh() {
data = await m.ReadDb()
v.SetData(data)
}然而,UI冻结在await m.ReadDb()上。我认为,因为OnRefresh返回void,它将返回并完成父方法(OnClick)的执行。然后,一旦await完成,它就会摆脱v.SetData(d)。出于某种原因,这不是我得到的输出。
发布于 2018-05-03 08:32:10
实际上,我的方法是正确的,但实现是不正确的。我原以为await m.ReadDb()会在一个工作线程中运行,但事实并非如此。原因是我必须使用Task.Run和await显式地请求它:
OnRefresh()
{
var d = await Task.Run (() => m.ReadDb());
v.SetData(d)
}仅仅编写await并不能创建一个新线程,这就是UI被阻塞的原因。
看看my other question in SO,它是在哪里被指给我的。
发布于 2018-05-01 12:32:55
就像这样:
class View {
IPresenter p;
void onClick() {
p.OnRefresh()
}
void setData() {
}
}
class Presenter implements Listener {
void OnRefresh() {
// You can do it with newThread or anything that does async
async (
m.readDB()
)
}
void onComplete(Data data) {
// or you can put it on Model class.
new Handler(Looper.getMainLooper()).post(() -> {
// this will be run on ui (or main) thread.
v.setData(data);
})
}
}
class Model {
Listener lstr;
void readDB() {
// read data..
// completed
lstr.onComplete(data)
}
}
interface Listener {
void onComplete(Data data)
}您还可以添加onFailure()和其他方法,RxJava也使这一点更加简单--看看它。
注意:在这里你需要担心的另一件事是由view引起的循环引用,它有一个ref到演示者,一个演示者有一个ref来查看。一旦您不再需要它(可能是onDestroy),您就需要手动销毁它,否则就会发生内存泄漏。
https://stackoverflow.com/questions/50114561
复制相似问题