MVP + Interactors

时间:2018-05-01 09:59:10

标签: c# android xamarin xamarin.android

鉴于以下流程:

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

  • OnClick(按系统划分):ui
  • OnRefresh(1):ui
  • ReadDb(2):worker
  • SetData(3):ui

我可以通过ReadDb async 等待来实现这一目标,但它会冻结UI线程。

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

感谢。

修改

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

最简单的方法是使用tasktawait

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

然而,用户界面在await m.ReadDb()冻结了。我认为,因为OnRefresh返回void,它将返回并完成父方法(OnClick)的执行。然后,await完成后,它将执行v.SetData(d)。出于某种原因,这不是我得到的输出。

2 个答案:

答案 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,指出我的位置。