繁体   English   中英

MVP +互动者

[英]MVP + Interactors

给定以下流程:

我希望这些线程执行这些方法:

  • OnClick (按系统):ui
  • OnRefresh (1):用户界面
  • ReadDb (2):工作者
  • SetData (3):用户界面

我可以通过使ReadDb 异步等待它来实现此目的,但是它将冻结UI线程。

您能想到一种不涉及实现InteractorsAsyncTask等的方法吗?

谢谢。


编辑

我正在寻找一种优雅的解决方案,请避免在View每个方法中使用new Handler (Looper.getMainLooper()).post(...)RunOnUiThread这样的包装器。

最简单的方法是使用tasktawait

async OnRefresh() {
    data = await m.ReadDb() 
    v.SetData(data)
}

但是,UI在await m.ReadDb()冻结。 我以为,因为OnRefresh返回void ,它将返回并完成执行父方法( OnClick )。 然后,一旦完成await ,它将执行v.SetData(d) 由于某种原因,这不是我得到的输出。

像这样:

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具有对主持人的引用而presenter具有要查看的引用的原因。 一旦不再需要ref(可能是onDestroy),则需要手动销毁该ref,否则会发生内存泄漏。

实际上我的方法是正确的,但是实现是不正确的。 我期望await m.ReadDb()在工作线程中运行,但事实并非如此。 这样做的原因是,我不得不使用Task.Run明确要求它并await它:

OnRefresh() 
{
    var d = await Task.Run (() => m.ReadDb());
    v.SetData(d)
}

只写await并不会创建新线程,这就是UI被阻止的原因。

在SO中检查我的其他问题 ,在此向我指出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM