Как передать контекст статическому методу? - PullRequest
0 голосов
/ 07 июля 2019

В моем фрагменте я вызываю статический метод из другого класса

if (getActivity() != null) {
        Main.bindMusicService(getActivity().getApplicationContext(), position, songList);
}

Основной класс:

private static Context context;

private static ArrayList<Song> songList;

private static int songIndex;

public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
    context = c;
    songIndex = songPos;
    songList = songs;
    /*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
    if (!mServiceIsBound) {
        try {
            mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
            c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
        } catch (Exception e) {
            Log.e("Main", "Service is not bound!");
        }
    }else{
        Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
    }
    Log.i("Main","Service is bound!");
}

Я получаю это предупреждение для контекста

Do not place Android context classes in static fields; this is a memory leak

Как правильно отправить мой массив, позицию адаптера и контекст другому методу, который находится в другом классе?

Ответы [ 3 ]

3 голосов
/ 07 июля 2019

Ваша проблема не отправка Context.Ваша проблема:

private static Context context;

Если вы абсолютно уверены, что вам нужно что-то подобное, замените его на:

private static Application context;

Настройте свой метод так, чтобы в качестве параметра использовался Applicationи пусть ваш вызов этого метода использует getApplication() вместо getApplicationContext().

IOW, ваш код достаточно безопасен - вы используете контекст Application - но детали вашего кода делают Lintнервничал.

0 голосов
/ 08 июля 2019

Другим простым способом может быть предоставление открытого метода get в классе приложения, который возвращает контекст члена экземпляра класса, и контекст инициализируется в методе oncreatw класса приложения вашего приложения.

0 голосов
/ 07 июля 2019

В Java статическая переменная или константа не будут собираться мусором.поэтому лучше избегать сохранения Context в статической переменной

public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
context = c;//remove this line

songIndex = songPos;
songList = songs;
/*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
if (!mServiceIsBound) {
    try {
        mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
        c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    } catch (Exception e) {
        Log.e("Main", "Service is not bound!");
    }
}else{
    Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
}
Log.i("Main","Service is bound!");
}

. Передача Context в статический метод - это нормально, просто НЕ сохраняйте его в статической переменной.

в основном, я думаю, что вам нужен лучший способ, чем передача контекста в методы, вы можете использовать кинжал, наконец, если у вас нет выбора, лучше использовать шаблон Singleton или глобальный контекст приложения, который является традиционным.

пример кинжала:

@Module
public class MainActivityModule {    
    private final Context context;

    public MainActivityModule (Context context) {
    this.context = context;
}

@Provides //scope is not necessary for parameters stored within the module
    public Context context() {
        return context;
    }
}

@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
    Context context();

    void inject(MainActivity mainActivity);
}

и затем

MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(MainActivity.this))
.build();

в качестве примера шаблона Singleton

private static SingletonDemo instance;

    public static SingletonDemo get() {
       if(instance == null) instance = getSync();
           return instance;
    }

    private static synchronized SingletonDemo getSync() {
       if(instance == null) instance = new SingletonDemo();
       return instance;
    }

    private SingletonDemo(){ 
        App.get();
    }

Уровень приложенияконтекст:

public class App extends Application {
    private static App instance;
public static App get() { return instance; }

@Override
public void onCreate() {
  super.onCreate();
  instance = this;
   }
}

вы должны определить класс приложения на AndroidManifest.xml

<application 
    ...
    android:name="com.example.YourApplication" >
    ...
</application>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...