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

时间:2016-11-25 18:38:42

标签: android mvp

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

MediaPlayer需要创建上下文。

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

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

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

3 个答案:

答案 0 :(得分:7)

Context是MVP中Android View图层的一部分,因此Presenter一定不能了解它,您不应将其传递给presenter

您必须向View接口添加一个方法,并在您的android视图组件(即ActivityFragment)中实现它,并使用它们在{{1}中执行操作层播放声音。

View必须要求提供UI事件,Presenter必须处理它!

以下是使用 Dagger RxJava Retrofit MVP 示例,这可能有助于您了解更多信息关于Android中的MVP:

https://github.com/mmirhoseini/marvel

答案 1 :(得分:6)

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

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

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

查看类:这是一个存储所有视图的地方,例如button,textview ......并在此图层上为这些视图组件设置所有侦听器。此视图上,您​​还可以在以后为演示者实现定义一个Listener类。您的视图组件将调用此侦听器类上的方法。

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

经理类:这是核心业务逻辑代码。也许一位主持人会有很多经理(取决于视图的复杂程度)。通常我们通过Context等注入框架获得Dagger类。

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实现(核心流程是相同的,但少数群体是不同的)。所以我在这里介绍了我经常在工作中使用的工作流程。希望你看到这个有用:)

答案 2 :(得分:0)

如果你需要一个通用的Context,你可以扩展Application,声明一个静态的上下文变量,然后你可以将这个Context带到你的演示者。