【发布时间】:2018-06-01 15:15:07
【问题描述】:
我将引用的代码来自一个与googlecodelabs/android-testing 非常相似的应用程序。
出于多种原因,我们希望遵循 MVP 模式,因此我们希望尊重依赖倒置原则,并且永远不要让 Presenter 知道活动、片段或任何与上下文相关的对象。
同时,我们希望 View 尽可能保持愚蠢,只将用户交互转发给将负责最终更新 View 的演示者。
所以一个经典的场景是当用户按下重新加载按钮时,View 将事件转发给 Presenter,Presenter 将调用 Model 以获取新数据并通过某种方式将其传递回 View .showStuff(stuff)回调。
问题是:你如何处理其中的多线程?模型将进行网络调用,而您不希望(甚至不能)在 UI 线程上执行此操作。
我所做的,但我不确定这是一个好方法(带来一些丑陋和样板)是让所有事件报告(从 View 到 Presenter 的调用)在单独的线程上运行(每次创建一个新线程,这不是一个坏习惯吗?):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_articles);
mPresenter = new ArticlesPresenter(this, Injector.provideArticlesRepository());
new Thread(() -> {
mPresenter.loadArticles(true);
}).start();
}
@Override
public void onClick(View v) {
new Thread(() -> {
mPresenter.loadArticle(articleId);
}).start();
}
由于来自 Presenter 的回调现在将来自非 UI 线程,我们需要确保所有 UI 更新都在 UI 线程上运行:
@Override
public void setProgressIndicator(boolean active) {
runOnUiThread(() -> {
Log.i(TAG, "set progress indicator : "+active);
Toast.makeText(this, "progress indicator: "+active, Toast.LENGTH_SHORT).show();
});
}
@Override
public void showArticles(Map<String, List<Article>> articles) {
runOnUiThread(() -> {
Log.i(TAG, "show articles, keys: " + articles.keySet());
Toast.makeText(this, "show all articles", Toast.LENGTH_SHORT).show();
});
}
我试过了,效果很好,但我认为我们可以做得更好。有什么建议吗?
【问题讨论】:
标签: java android multithreading android-mvp