[英]Android - MVP using Activity/Context
I've been dabbling with MVP for android and have read from different sites about not passing an activity as argument into the presenter as it's anti-pattern but i have come across a problem where i need to use a third party method that requires the activity/context. 我一直在尝试Android的MVP,并从不同的站点阅读有关不将活动作为参数传递给演示者的信息,因为这是一种反模式,但是我遇到了一个问题,我需要使用需要该活动的第三方方法/上下文。
I've thought of using Dependency Injection, doing another abstraction or just pass it only to the method that requires it, rather than the constructor but i'm confused with what's better. 我曾经考虑过使用依赖注入,进行另一种抽象,或者仅将其传递给需要它的方法,而不是传递给构造函数,但我对更好的方法感到困惑。
An example in Kotlin (Presenter) Kotlin(Presenter)中的一个例子
fun Food(*should activity be passed here?*) {
var bar = Foo(activity).build
Stand(bar, callback{})
}
Would be great if someone can enlighten me on this. 如果有人可以启发我,那就太好了。
I don't think any obvious reason why you should avoid passing Activity Context to Presenter. 我认为您应该避免将Activity Context传递给Presenter的任何明显原因。 I heard that you should make presenter independent of any Android packages because you can reuse them for Desktop/TV or other platforms, but I don't think this will work.
我听说您应该使主持人独立于任何Android程序包,因为您可以将其重用于桌面/电视或其他平台,但是我认为这不起作用。
If you need activity in your presenter you have several ways to do it (my DI cases will use Dagger2 library but you can take a look at another ones): 如果您需要在演示者中进行活动,则有几种方法可以进行(我的DI案例将使用Dagger2库,但您可以看一下其他案例):
Just pass activity in setter/constructor, to make it safer use WeakReference. 只需在setter / constructor中传递活动,以使其更安全地使用WeakReference。 This is how we do it in our project.
这就是我们在项目中做到的方式。
public class BasePresenter implements IPresenter { 公共类BasePresenter实现IPresenter {
protected VIEW view; private WeakReference<FragmentActivity> activityWeakReference = new WeakReference<>(null); @Override public void onStart(FragmentActivity activity) { activityWeakReference = new WeakReference<>(activity); } @Override public void onStop() { activityWeakReference.clear(); } @Override public void onViewCreated(Bundle savedInstanceState) { } public Optional<FragmentActivity> getActivity() { return Optional.ofNullable(activityWeakReference.get()); } public void getActivity(Action1<FragmentActivity> action) { getActivity().ifPresent(action::call); } @Override public void setView(VIEW view) { this.view = view; } @Override public boolean onBackPressed() { return false; } @Override public void navigationButtonClick() { getActivity(Activity::finish); } @Override public boolean onCustomActivityResult(int requestCode, int resultCode, Intent data) { return false; }}
Do not forget to null your activity when presenter not needed anymore, because they are huge in memory so it will cause leaks. 当不再需要演示者时,请不要忘记将您的活动为空,因为它们的内存很大,因此会导致泄漏。
If you want to work in a "clean way" you should always push the frameworks (android, third party libraries, data sources...) to the outer layer of your architecture (as far as possible from your business logic). 如果要以“干净的方式”工作,则应始终将框架(android,第三方库,数据源...)推送到体系结构的外层(尽可能远离业务逻辑)。
In your case I would create a "wrapper class" for the 3rd party library and the context and I would inject the interface of this class as a constructor parameter of your presenter. 在您的情况下,我将为第三方库和上下文创建一个“包装器类”,并将该类的接口作为演示者的构造函数参数注入。 In this way your presenter is clean and is not affected if you have to change the 3rd party library.
这样,您的演示者是干净的,并且如果您必须更改第三方库,则不会受到影响。
Here you can read more about clean architecture: 在这里,您可以阅读有关干净架构的更多信息:
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
https://github.com/android10/Android-CleanArchitecture https://github.com/android10/Android-CleanArchitecture
https://android.jlelse.eu/a-complete-idiots-guide-to-clean-architecture-2422f428946f https://android.jlelse.eu/a-complete-idiots-guide-to-clean-architecture-2422f428946f
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.