Как сохранить один экземпляр MediaPlayer [Android]

Я использую класс Android Media Player для воспроизведения звука уведомлений в моем приложении Android.

MediaPlayer player = MediaPlayer.create(getApplicationContext(), R.raw.notify);
player.setLooping(false);
player.start();

Мне нужно воспроизводить разные звуки уведомлений в разных видах деятельности, поэтому каждый раз, когда мне нужно воспроизвести звук, мне нужно создать экземпляр медиаплеера, а затем сказать «начать».

Но вместо этого, как я могу поддерживать один экземпляр медиаплеера во всем приложении и использовать его во всех действиях для воспроизведения звуков.

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

Благодарность

 User772333715 мая 2012 г., 10:05
Спасибо за повтор, мне нужно позвонитьplayer.release() каждый раз, когда я заканчиваю проигрывание медиа-файла или могу ли я вызвать это после выхода из приложения или когда мой синглтон-класс разрушается. когда я вызываю release, мне нужно снова вызывать create.

Ответы на вопрос(3)

Я всегда делаю то же самое с модифицированной версиейSingleton Pattern. Поскольку контекст нужен везде в Android, я передаю контекст экземпляру:

public class Asset{
     public static Asset(Context context);
}

В этой реализации вы также можете использовать разные синглтоны в разных контекстах, например:

private static Hashtable<Context, Asset> instances;

public static Asset(Context context){
    if (!instances.containKey(context)){
        instances.put(context, new Asset(context));

    return instances.get(context);
}

Преимущество этого по сравнению с классическим синглтоном заключается в том, что вы можете определить сферу своих синглетонов. Иногда вам просто нужно, чтобы экземпляр оставался в той же операции, но вторая активность может иметь другой экземпляр. Если вам это нужно для разных Activity, вам просто нужно передать context.getApplicationContext ().

Решение Вопроса

Синглтон. Сделайте класс MyPlayer, который имеет статический методgetMediaPlayer(), который возвращает один и тот же экземпляр MediaPlayer при каждом вызове.

 Ankit Srivastava11 авг. 2013 г., 20:20
Не могли бы вы рассказать подробнее?
 waqaslam15 мая 2012 г., 08:53
+ 1 за то, что я собирался написать
Разрабатывая немного больше о синглтоне:

Примечание: здесь также решается проблема сбоя Audioservice при последовательном создании серии проигрывателей (скажем, 20 mediaPlayers).

Создание плеера: Класс singleton должен создать другой поток для обработки операций медиаплеера (не основного потока пользовательского интерфейса)

Создать Player Runnable: Этот поток (созданный экземпляром синглтона должен иметь приоритет фона, задержка «Thread.sleep (500);» перед логикой создания, чтобы позволить AudioService, используемому MediaPlayer.create () - завершить свою работу, так как более поздний метод возвращается мгновенно.

Создать код запуска игрока:

/**
 * Created by George hannuneh on 10/12/2015.
 * Holds the background work for creating a media player
 */
public class CreatePlayerRunnable implements Runnable {

static final int CREATE_STATE_FAILED = -1;
static final int CREATE_STATE_STARTED= 0;
static final int CREATE_STATE_COMPLETED= 1;
private static final String TAG ="CreatePlayerRunnable";
private static int sRunnablesCount = 1;


final TaskRunnableCreatePlayerMethods mPlayerTask;

/**
 *
 * An interface that defines methods that PlayerCreationTask implements. An instance of
 * CreatePlayerTask passes itself to an CreatePlayerRunnable instance through the
 * CreatePlayerRunnable constructor, after which the two instances can access each other's
 * variables.
 */
interface TaskRunnableCreatePlayerMethods {
    /**
     * Sets the Thread that this instance is running on
     * @param currentThread the current Thread
     */
    void setCreatePlayerThread(Thread currentThread);

    Context getActivity();

    Uri getMediaUri();

    void handleCreationState(int createStateFailed);

    void setPlayer(MediaPlayer returnMediaPlayer);

    String getPlayerId();

    MediaPlayer getPlayer();
}
/**
 * This constructor creates an instance of CreatePlayerRunnable and stores in it a reference
 * to the CreatePlayerTask instance that instantiated it.
 *
 * @param createPlayerTask The CreatePlayerTask
 */
CreatePlayerRunnable(TaskRunnableCreatePlayerMethods createPlayerTask) {
    mPlayerTask = createPlayerTask;
}
@Override
public void run() {
    /*
     * Stores the current Thread in the CreatePlayerTask instance,
     * so that the instance
     * can interrupt the Thread.
     */
    mPlayerTask.setCreatePlayerThread(Thread.currentThread());
    // Moves the current Thread into the background
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
    MediaPlayer returnMediaPlayer = null;

    try {

        Thread.sleep(500);
        // Before continuing, checks to see that the Thread hasn't
        // been interrupted
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
        returnMediaPlayer = MediaPlayer.create(mPlayerTask.getActivity(), mPlayerTask.getMediaUri());
        if (returnMediaPlayer == null) {
            Log.e("CreatePlayerRunnable", mPlayerTask.getMediaUri()+ " - failed to create player");
            return;
        }
        PlayerEventsHandler playerEvents = new PlayerEventsHandler(mPlayerTask.getPlayerId());
        returnMediaPlayer.setLooping(true);
        returnMediaPlayer.setOnCompletionListener(playerEvents);
        returnMediaPlayer.setOnErrorListener(playerEvents);
        returnMediaPlayer.setVolume(0f, 0f);
        returnMediaPlayer.start();
    } catch (InterruptedException e1) {
        // Does nothing
    } catch(Exception e)
    {
        returnMediaPlayer = null;
        e.printStackTrace();
    }
    finally {
        if(MainActivity.DEBUG_MODE_ENABLED){
            Log.d(TAG, "end of runnable: "+ sRunnablesCount++);
        }
        if (null == returnMediaPlayer){
            mPlayerTask.handleCreationState(CREATE_STATE_FAILED);
        } else {
            mPlayerTask.setPlayer(returnMediaPlayer);
            // Reports a status of "completed"
            mPlayerTask.handleCreationState(CREATE_STATE_COMPLETED);
        }

        // Sets the current Thread to null, releasing its storage
        mPlayerTask.setCreatePlayerThread(null);
        // Clears the Thread's interrupt flag
        Thread.interrupted();
    }

}

}

 Yarh27 нояб. 2015 г., 08:49
Есть ли необходимость в отдельном запуске, если я запускаю медиаплеер из сервиса?
 hannunehg29 нояб. 2015 г., 11:07
то нужно, так это минимизировать многопоточный доступ к лежащей в основе C ++ lib, которая декодирует mp3 (FFPEG), так как в нем есть некоторые ошибки при многопоточном доступе. Как вы решите, решать вам, я в итоге сменил формат на .ogg, а когда дело доходит до mp4, я просто использовал exoplayer из google

Ваш ответ на вопрос