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

Android MVP: which layer should store context variable

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

MediaPlayer 需要创建上下文。

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

我应该将上下文传递给演示者方法并在那里播放吗?

或者只在视图上播放是否可以。

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

Context 是 MVP 中 Android View 层的一部分,所以 Presenter 一定不知道它,你不应该把它传递给 presenter.

您必须向 View 接口添加一个方法并在 android 视图组件(即 ActivityFragment)中实现它并使用它们来做View 层中播放声音的动作。

Presenter 必须请求 UI 事件并且 View 必须处理它!

这是一个使用 DaggerRxJavaMVP 示例Retrofit,这可能有助于您在 Android:

中了解有关 MVP 的更多信息

https://github.com/mmirhoseini/marvel

我经常将业务逻辑代码放在模型层(不要与数据库中的模型混淆)。我经常重命名为 XManager 以避免混淆(例如 ProductManagerMediaManager ...),因此演示者 class 仅用于保持工作流程。

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

例如,这是我的 mvp 工作流程。

视图class:这是一个你存储所有视图的地方,比如按钮,文本视图......你为这些视图组件设置所有监听器层。同样在此视图上,您​​稍后为演示者实现定义一个监听器 class。您的视图组件将调用此侦听器上的方法 class.

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 class: 这是你在里面存放视图和模型的地方,供以后调用。此外,presenter class 将实现上面定义的 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();
    }
}

Manager class: 下面是核心业务逻辑代码。也许一个演示者将有多个经理(取决于视图的复杂程度)。经常我们通过一些注入框架如Dagger.

得到Contextclass
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();
   }
}

最后: 将这些东西放在 Activities、Fragments 中……这是您初始化视图、管理器并将它们全部分配给演示者的地方。

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();
   }
}

你看到每个演示者、模型、视图都被一个接口包裹着。这些组件将通过接口调用。这样的设计会让你的代码更健壮,以后更容易修改。

回答你的问题这么长post。我认为这是合适的,因为每个人都有自己的 MVP 实现(核心流程相同,但少数人不同)。所以我在这里介绍一个我在工作中经常使用的工作流程。希望你看到这个有用:)