Как получить контекст из класса неактивности?

Я нашел один ответ, который, как представляется, должен создать отдельный класс и создать статический объект MyApplication и сделать метод get. Тогда любой класс может вызвать MyApplication.get() для извлечения контекста.

Есть ли другой чистый способ? Это моя ситуация:

У меня есть класс A и класс B. Класс A содержит объект из класса B (пусть вызовет объект b). В классе A я вызываю "b.play()". Однако я получаю исключение с нулевым указателем, потому что класс B должен передать контекст методу MediaPlayer.create().

До сих пор я скинул хак и из класса A, который я назвал.... "b.play(this)", и просто передал контекст Б. Однако это довольно уродливо и выглядит как плохое использование ООП.

Любые мысли?

Ответ 1

Если для класса B требуется Контекст для работы, то я не вижу никаких проблем, связанных с тем, что класс A предоставляет ему (через параметр метода воспроизведения, параметр в конструкторе и т.д.).

Я не думаю, что вы делаете плохой ООП, предоставляя классу B зависимости, которые ему необходимы для выполнения этой работы.

Ответ 2

Эта проблема, похоже, очень сильно развивается в разработке Android. Одним из решений для получения ссылки на конкретный Контекст является подклассификация приложения и получение ссылки на требуемый контекст.

public class MyApplication extends Application { 

private Context context;

@Override
public onCreate() {
  super.onCreate();
  this.context = getApplicationContext() // Grab the Context you want.
}

public static Context getApplicationContext() { return this.context; }
}

Однако это решение требует указания имени вашего подкласса в манифесте.

<application
    android:name=".MyApplication"
</application>

Затем вы можете использовать это в любом месте своего приложения, как это, в классах неактивности.

MyApplication.getContext();  // Do something with the context! :)

Ответ 3

Передача this вокруг - жизнеспособный способ делать вещи, особенно если this - это активность, которая создает объект, нуждающийся в Контексте. Иногда я помещаю Контекст в конструктор (например, public MyObject(Context context){this.context = context;}), так что вам не нужно отправлять его каждый раз. Однако, если ваш объект разделяется несколькими действиями, вы должны, вероятно, обновить контекст, на который он смотрит, с новым действием, хотя я не проверял, что произойдет, если вы используете старую активность.

Ответ 4

Я также ответил здесь.

Вы можете сделать это, используя ContextWrapper, как описано здесь.

Например:

public class MyContextWrapper extends ContextWrapper {

    public MyContextWrapper(Context base) {
      super(base);
   }

   public void someMethod() {
      // MediaPlayer.create(this, ...)
   }

}