Android MVP:哪一层应该存储上下文变量
Android MVP: which layer should store context variable
我发现自己需要在用户单击视图上的按钮时播放声音文件。
MediaPlayer 需要创建上下文。
放置 MediaPlayer 初始化代码的最佳方式是什么?
我应该将上下文传递给演示者方法并在那里播放吗?
或者只在视图上播放是否可以。
如果你需要一个通用的上下文,你可以扩展应用程序,声明一个静态上下文变量,然后你可以将这个上下文放入你的演示者中。
Context
是 MVP 中 Android View
层的一部分,所以 Presenter
一定不知道它,你不应该把它传递给 presenter
.
您必须向 View
接口添加一个方法并在 android 视图组件(即 Activity
或 Fragment
)中实现它并使用它们来做View
层中播放声音的动作。
Presenter
必须请求 UI 事件并且 View
必须处理它!
这是一个使用 Dagger、RxJava 和 的 MVP 示例Retrofit,这可能有助于您在 Android:
中了解有关 MVP 的更多信息
我经常将业务逻辑代码放在模型层(不要与数据库中的模型混淆)。我经常重命名为 XManager
以避免混淆(例如 ProductManager
、MediaManager
...),因此演示者 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
.
得到Context
class
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 实现(核心流程相同,但少数人不同)。所以我在这里介绍一个我在工作中经常使用的工作流程。希望你看到这个有用:)
我发现自己需要在用户单击视图上的按钮时播放声音文件。
MediaPlayer 需要创建上下文。
放置 MediaPlayer 初始化代码的最佳方式是什么?
我应该将上下文传递给演示者方法并在那里播放吗?
或者只在视图上播放是否可以。
如果你需要一个通用的上下文,你可以扩展应用程序,声明一个静态上下文变量,然后你可以将这个上下文放入你的演示者中。
Context
是 MVP 中 Android View
层的一部分,所以 Presenter
一定不知道它,你不应该把它传递给 presenter
.
您必须向 View
接口添加一个方法并在 android 视图组件(即 Activity
或 Fragment
)中实现它并使用它们来做View
层中播放声音的动作。
Presenter
必须请求 UI 事件并且 View
必须处理它!
这是一个使用 Dagger、RxJava 和 的 MVP 示例Retrofit,这可能有助于您在 Android:
中了解有关 MVP 的更多信息我经常将业务逻辑代码放在模型层(不要与数据库中的模型混淆)。我经常重命名为 XManager
以避免混淆(例如 ProductManager
、MediaManager
...),因此演示者 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
.
Context
class
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 实现(核心流程相同,但少数人不同)。所以我在这里介绍一个我在工作中经常使用的工作流程。希望你看到这个有用:)