Я оказываюсь там, где мне нужно воспроизвести звуковой файл, когда пользователь нажимает кнопку в представлении.

MediaPlayer требует создания контекста.

Как лучше всего поставить код инициализации MediaPlayer?

Должен ли я передать контекст в метод презентатора и воспроизвести его там?

Или можно просто поиграть на просмотре.

9
Zhen Liu 25 Ноя 2016 в 21:38

3 ответа

Лучший ответ

Context является частью уровня Android View в MVP, поэтому Presenter не должен иметь о нем представления, и вы не должны передавать его presenter.

Вам необходимо добавить методы в интерфейс View и реализовать их внутри компонентов представления Android (например, Activity или Fragment) и использовать их для выполнения действий на уровне View. как воспроизведение звука.

Presenter должен запросить событие пользовательского интерфейса, а View должен его обработать!

Вот пример MVP с использованием Dagger , RxJava и Retrofit , который может помочь вам узнать больше о MVP в Android:

https://github.com/mmirhoseini/marvel

9
Vadim Kotov 1 Фев 2019 в 14:13

Если вам нужен общий контекст, вы можете расширить приложение, объявить статическую переменную контекста и после этого передать этот контекст своему докладчику.

0
GiuseppeLabanca 25 Ноя 2016 в 19:16

Я часто помещаю код бизнес-логики в уровень модели (не путайте с моделью в базе данных). Я часто переименовываю его в XManager, чтобы избежать путаницы (например, ProductManager, MediaManager ...), поэтому класс докладчика просто используется для поддержания рабочего процесса.

Практическое правило - запретить или хотя бы ограничить импорт пакета Android в классе докладчика. Эта передовая практика облегчит вам тестирование класса презентатора, потому что теперь презентатор представляет собой простой Java-класс, поэтому нам не нужна платформа Android для тестирования этих вещей.

Например, вот мой рабочий процесс mvp.

Класс представления : это место, где вы храните все ваши представления, такие как кнопка, текстовое представление ... и вы устанавливаете всех слушателей для этих компонентов представления на этом уровне. Также в этом представлении вы определяете класс слушателя для последующих реализаций презентатора. Компоненты вашего представления будут вызывать методы этого класса слушателя.

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: здесь вы сохраняете вид и модель для последующего вызова. Также класс презентатора будет реализовывать интерфейс 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 (основной поток такой же, но меньшинства разные). Я представляю здесь рабочий процесс, который часто использую в работе. Надеюсь, вы увидите это полезным :)

7
hqt 27 Ноя 2016 в 06:35