鉴于以下流程:
我希望这些方法执行这些方法:
OnClick
(按系统划分):ui OnRefresh
(1):ui ReadDb
(2):worker SetData
(3):ui 我可以通过ReadDb
async 和等待来实现这一目标,但它会冻结UI线程。
您能想到一种不涉及实施Interactors
,AsyncTask
等的方法吗?
感谢。
修改
我正在寻找一个优雅的解决方案,请避免在new Handler (Looper.getMainLooper()).post(...)
等的每个方法中使用RunOnUiThread
,View
等包装。
最简单的方法是使用taskt
和await
:
async OnRefresh() {
data = await m.ReadDb()
v.SetData(data)
}
然而,用户界面在await m.ReadDb()
冻结了。我认为,因为OnRefresh
返回void
,它将返回并完成父方法(OnClick
)的执行。然后,await
完成后,它将执行v.SetData(d)
。出于某种原因,这不是我得到的输出。
答案 0 :(得分:0)
这样的事情:
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,一旦你不再需要它(可能是onDestroy)或者会发生内存泄漏。
答案 1 :(得分:0)
实际上我的方法是正确的,但实施是不对的。我期待ApproveButton
在一个工作线程中运行,但事实并非如此。原因是,我必须明确要求await m.ReadDb()
和Task.Run
:
await
只是写OnRefresh()
{
var d = await Task.Run (() => m.ReadDb());
v.SetData(d)
}
不会创建新线程,这就是UI被阻止的原因。
检查my other question in SO,指出我的位置。