How to maintain single instance of MediaPlayer [Android]

后端 未结 3 1044
渐次进展
渐次进展 2021-01-18 21:40

I am using android media player class for playing notification sound in my android Application.

MediaPlayer player = MediaPlayer.create(getApplicationContext         


        
3条回答
  •  无人及你
    2021-01-18 22:12

    Elaborating a bit more on singleton considerations:

    Note: here, the problem of Audioservice failure when creating a series of players consecutively (say 20 mediaPlayers) is addressed too.

    Creating the player: The singleton class should create another thread to handle the mediaplayer operations (not the main UI thread)

    Create Player Runnable: This thread (created by the singleton instance should be given background priority, a delay of "Thread.sleep(500);" before creation logic to allow the AudioService- used by the MediaPlayer.create()- to finish its work since the later method returns instantly.

    Create Player Runnable code:

    /**
     * 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();
        }
    
    }
    

    }

提交回复
热议问题