Android 模型-视图-展示器(MVP):如何返回长时间运行的 AsyncTask

4

我对 Android 还不是很熟悉,正在编写一个应用程序。我已经开始更深入地测试我的代码,因此,我想实现MVP设计策略,因为它可以为代码添加更多可测试层。使用MVP的一个假定好处是如何在动态执行AsyncTasks的过程中帮助。由于您希望在Presenter类中避免任何特定于Android的组件,因此该怎么引用使用AsyncTasksActivity呢?关于MVP的教程显示,Presenter对象具有以Activity作为参数并返回给它的方法;但是,如果您的AsyncTask需要很长时间,并且您的Activity已被销毁,例如因旋转更改,那么您该如何返回到正确的Activity呢?我目前将我的AsyncTask存储在Fragment中,以便在方向更改时保存。我很难找到实现MVP实践的解决方法。

2个回答

4
为了回答你的问题,你无法避免将Android类传递到Presenter类中。但是,不要将Android对象作为参数传递,而是向View类添加一个返回它的方法(例如getActivity())。
话虽如此,我强烈建议您使用Loader而不是AsyncTask。Loaders是专门为您的用例设计的。它们也可以在后台运行,但其生命周期与ActivityFragment的生命周期绑定。
如果您切换到Loaders,请向View接口添加一个像getLoaderManager()的方法。

谢谢您的回复!我想知道如果我想在Presenter中执行AsyncTask/Loader功能,而不是在Loader中执行,那么在方向更改后如何引用Activity。例如,我不认为Presenter会是Parcelable或Serializable,因此我不认为在onDestroy()之后从Activity到Presenter的引用将可能被维护,而且我也不认为Presenter能够知道哪个Activity将成为onDestroy()方法的对象。 - user6542934
1
@Barry Fruitman - 你可以通过传递抽象而不是Android类来避免将Android类传递给Presenter。例如,使Presenter依赖于View接口而不是显式的“Activity”实例,并让相关的“Activity”实现该接口。此外,我很久以前就停止使用它们了(因此如果底层实现已更新,请纠正我),但是“Loader”不与“Activity” /“Fragment”的生命周期绑定。按Home按钮或执行方向更改不会停止Loader的后台线程执行其工作。 - homerman
@James,我一直使用的MVP模式是让View构建并保留Presenter,而不是反过来。然后,View向Presenter注册自己(例如Presenter.setView()),并在销毁时取消注册。话虽如此,你要寻找的解决方案是不要在方向更改时销毁Activity。你应该能够通过Google或SO搜索很容易找到如何做到这一点。 - Barry Fruitman
@James 请考虑将此答案标记为正确答案。 - Barry Fruitman

1
如果我没有误解您的问题,您正在尝试使用“保留非UI片段”来进行“长时间运行的任务”,对吗? 以下是我的建议:
1. 为您的Activity创建ActivityView接口 2. 在Fragment Presenter中使用WeakReference 引用您的Activity(以避免内存泄漏问题) 3. 当Activity重新创建时,尝试获取您的保留片段,并重置Fragment Presenter的ActivityView。 您可以查看此Google Example以了解如何处理配置更改时的数据加载。
总之,只需使用WeakReference避免内存泄漏问题,并在重新创建Activity时尝试重新设置Presenter的view即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接