Android MVP:哪一层应该存储上下文变量

Android MVP:哪一层应该存储上下文变量,android,mvp,Android,Mvp,当用户单击视图上的按钮时,我发现自己需要播放声音文件 MediaPlayer需要创建上下文 放置MediaPlayer初始化代码的最佳方式是什么 我应该将上下文传递给presenter方法并在那里播放吗 或者只在视图上玩就可以了。如果您需要一个通用上下文,您可以扩展应用程序,声明一个静态上下文变量,然后将该上下文输入演示者。上下文是MVP中Android视图层的一部分,因此,Presenter不得对此有任何想法,也不应将其传递给Presenter Class MediaManagerImpl e

当用户单击视图上的按钮时,我发现自己需要播放声音文件

MediaPlayer需要创建上下文

放置MediaPlayer初始化代码的最佳方式是什么

我应该将上下文传递给presenter方法并在那里播放吗


或者只在视图上玩就可以了。

如果您需要一个通用上下文,您可以扩展应用程序,声明一个静态上下文变量,然后将该上下文输入演示者。

上下文
是MVP中Android
视图
层的一部分,因此,
Presenter
不得对此有任何想法,也不应将其传递给
Presenter

Class MediaManagerImpl extends MediaManager {
   // using Dagger for injection context if you want
   @Inject
   private Context context;
   private MediaPlayer mediaPlayer;

   // dagger solution
   public MediaPlayerManagerImpl() {
     this.mediaPlayer = new MediaPlayer(context);
   }

   // no dagger solution
   public MediaPlayerManagerImpl(Context context) {
     this.context = context;
     this.mediaPlayer = new MediaPlayer(context);
   }

   public void playMedia() {
     mediaPlayer.play();
   }

   public void stopMedia() {
      mediaPlayer.stop();
   }
}
public class MyActivity extends Activity {

   Presenter presenter;

   @Override
   public void onCreate() {
      super.onCreate();

      IView view = new ViewImpl();
      MediaManager manager = new   MediaManagerImpl(this.getApplicationContext());
      // or this. if you use Dagger
      MediaManager manager = new   MediaManagerImpl();
      presenter = new PresenterImpl(view, manager);
   }   

   @Override
   public void onStop() {
     super.onStop();
     presenter.onStop();
   }
}
您必须在
视图
界面中添加一个方法,并在android视图组件(即
活动
片段
)中实现它,并使用它们在
视图
层中播放声音时执行操作

演示者
必须请求UI事件,并且
查看
必须处理它

下面是一个使用Dagger、RxJava和改型的MVP示例,它可能会帮助您了解更多关于Android中MVP的信息:


我经常将业务逻辑代码放在模型层(不要与数据库中的模型混淆)。我经常重命名为
XManager
,以避免混淆(例如
ProductManager
MediaManager
…),所以presenter类仅用于保持工作流

经验法则是presenter类中没有或至少限制导入android软件包。这个最佳实践支持您更轻松地测试presenter类,因为presenter现在只是一个普通的java类,所以我们不需要android框架来测试这些东西

例如,这里是我的mvp工作流

class PresenterImpl extends Presenter implements ViewListener {
    private View view;
    private MediaManager mediaManager;

    public PresenterImpl(View, MediaManager manager) {
       this.view = view;
       this.manager = manager;
    }

    @Override
    public void playSong() {
       mediaManager.playMedia();
    }
}
视图类:这是一个存储所有视图的地方,例如按钮、文本视图。。。然后为该层上的视图组件设置所有侦听器。此外,在该视图上,您将为以后的presenter实现定义一个侦听器类。视图组件将调用此侦听器类上的方法

class ViewImpl implements View {
   Button playButton;
   ViewListener listener;

   public ViewImpl(ViewListener listener) {
     // find all view

     this.listener = listener;

     playButton.setOnClickListener(new View.OnClickListener() {
       listener.playSong();
     });
   }

   public interface ViewListener {
     playSong();
   }
}
Presenter类:这是存储视图和模型的地方,供以后调用。另外,presenter类将实现上面定义的ViewListener接口。演示者的要点是控制逻辑工作流

class PresenterImpl extends Presenter implements ViewListener {
    private View view;
    private MediaManager mediaManager;

    public PresenterImpl(View, MediaManager manager) {
       this.view = view;
       this.manager = manager;
    }

    @Override
    public void playSong() {
       mediaManager.playMedia();
    }
}
管理类:以下是核心业务逻辑代码。也许一个演示者会有许多管理者(取决于视图的复杂程度)。通常,我们通过一些注入框架(如
Dagger
)获得
Context

Class MediaManagerImpl extends MediaManager {
   // using Dagger for injection context if you want
   @Inject
   private Context context;
   private MediaPlayer mediaPlayer;

   // dagger solution
   public MediaPlayerManagerImpl() {
     this.mediaPlayer = new MediaPlayer(context);
   }

   // no dagger solution
   public MediaPlayerManagerImpl(Context context) {
     this.context = context;
     this.mediaPlayer = new MediaPlayer(context);
   }

   public void playMedia() {
     mediaPlayer.play();
   }

   public void stopMedia() {
      mediaPlayer.stop();
   }
}
最后:将这些东西放在活动、片段中。。。这里是您初始化视图、管理器并将所有内容分配给演示者的位置

public class MyActivity extends Activity {

   Presenter presenter;

   @Override
   public void onCreate() {
      super.onCreate();

      IView view = new ViewImpl();
      MediaManager manager = new   MediaManagerImpl(this.getApplicationContext());
      // or this. if you use Dagger
      MediaManager manager = new   MediaManagerImpl();
      presenter = new PresenterImpl(view, manager);
   }   

   @Override
   public void onStop() {
     super.onStop();
     presenter.onStop();
   }
}
您可以看到,每个演示者、模型和视图都由一个界面包装。这些组件将通过接口调用。这种设计将使您的代码更健壮,更便于以后修改


这是一篇很长的帖子来回答你的问题。我认为这是合适的,因为每个人都有自己的MVP实现(核心流程相同,但少数人不同)。因此,我在这里介绍了我在工作中经常使用的工作流。希望您能看到以下有用的内容:)

活动是一个上下文,您应该在活动内部编写该内容。否则,演示者不会让任何老师喜欢这个答案,因为它很短,回答了我的问题。我将基本上保持MediaPlayer/MediaRecorder逻辑的内部视图;这是内存泄漏(也破坏了即时运行),我需要在模型类中使用上下文来获取本地字符串(context.getString(R.string…),但我经常听说,业务逻辑应该只包含POJO,而不应该包含任何特定于android的类。然而,除了将上下文作为参数传递给模型之外,我还没有找到任何解决方案。MVVM在需要一些上下文资源的情况下能解决这个问题吗?