簡體   English   中英

如何使用MediaPlayer Singleton

[英]How to use a MediaPlayer Singleton

我是Android開發的新手,並且從一個簡單的音板應用程序開始。 我開始使用多個片段開發音板,直到意識到自己正在使用MediaPlayer的多個實例。 這不好,因為我一次只想播放一種聲音。

我意識到我必須使用MediaPlayer Singleton來解決我的問題。 唯一的問題是,我在網上找不到許多MediaPlayer Singleton的資源或示例。

這是我最初在每個片段中的每個“ onCreateView”中添加的內容:

public static class FragmentPage1 extends Fragment {

    int selectedSoundId;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_page1, container, false);


        final MediaPlayer player = new MediaPlayer();
        final Resources res = getResources();

        final int[] buttonIds = { R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4, R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9 };
        final int[] soundIds = { R.raw.sound01, R.raw.sound02, R.raw.sound03, R.raw.sound04, R.raw.sound05, R.raw.sound06, R.raw.sound07, R.raw.sound08, R.raw.sound09 };

        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int i = 0; i < buttonIds.length; i++) {
                    if (v.getId() == buttonIds[i]) {
                        selectedSoundId = soundIds[i];
                        AssetFileDescriptor afd = res.openRawResourceFd(soundIds[i]);
                        player.reset();
                        try {
                            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (IllegalStateException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        try {
                            player.prepare();
                        } catch (IllegalStateException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        player.start();
                        break;
                    }
                }
            }
        };

        for (int i = 0; i < buttonIds.length; i++) {
            ImageButton soundButton = (ImageButton) rootView.findViewById(buttonIds[i]);
            registerForContextMenu(soundButton);
            soundButton.setOnClickListener(listener);
        }
        return rootView;
    }
}

據我所知,我可能會將onClickListener放在每個片段中,並將MediaPlayer Singleton放在新的Java類中。 我不知道該怎么辦。

如何實現MediaPlayer Singleton,如何在片段的“ onCreateView”方法中調用它?

示例受到高度贊賞和感謝!

請參閱,Singleton是一種設計模式,它是通過將默認構造函數設置為private來實現的,那么您應該提供一個get方法,以便可以恢復對象實例。 查看下面的示例:

public class Foo {
    private MediaPlaye md;

    private Foo () {
        md = new MediaPlayer();
    }

    public MediaPlayer getMediaPlayer () {
        if (md == null) {
            new Foo();
        }
        return md;
    }
}

在您的情況下,最好的辦法是創建一個Service類,該類將封裝所有MediaPlayer方法。 之所以這樣做,是因為通常情況下,即使用戶離開了與其綁定的活動,開發人員也希望玩家繼續玩游戲。 在要使用MediaPlayer API的每個片段中,可以綁定服務並使用定義的接口。 看看下面的課程:

public class MusicPlayerService extends android.app.Service implements MediaPlayer.OnPreparedListener,
        MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener,
        ObserverSubject {

    private static final int NOTIFY_ID = 1;
    private List<MusicPlayerObserver> mObservers;

    private MediaPlayer mMediaPlayer;
    private final IBinder playerBind = new MusicBinder();;

    private List<Track> mPlaylist;
    private Integer mPosition;

    private Boolean isRepeating;
    private Boolean isShuffling;
    private Boolean isPrepared;
    private Boolean isPaused;

    // Callback Methods______________________________________________
    @Override
    public void onCreate() {
        ...
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        ...
    }

    @Override
    public IBinder onBind(Intent intent) {
        return playerBind;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        mMediaPlayer.stop();
        mMediaPlayer.release();
        return false;
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mp.reset();
        return false;
    }


    // UTIL METHODS__________________________________________________
    private Long getCurrentTrackId() {
        return mPlaylist.get(mPosition).getTrackId();
    }

    private Long getCurrentAlbumId() {
        return mPlaylist.get(mPosition).getAlbumId();
    }



    // MEDIA PLAYER INTERFACE________________________________________

    public void play() {
        ...
    }

    public void pause() {
        ...
    }

    public void resume() {
        ...
    }

    public void next() {
        ...
    }

    public void previous() {
        ...
    }

    public void seekTo(int pos) {
        ...
    }

    // SERVICE INTERFACE PROVIDER_____________________________________
    /**
     * Interface through the component bound to this service can interact with it
     */
    public class MusicBinder extends Binder {
        public MusicPlayerService getService() {
            return MusicPlayerService.this;
        }
    }
}

我強烈建議您遵循創建MusicPlayer服務的策略。 另外,我建議您看看另一個稱為觀察者的設計模式。 通常,在音樂應用程序中,您希望基於MP狀態更新多個UI元素。 觀察者非常適合這種情況。

希望我有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM