如何使用MediaPlayer Singleton [英] How to use a MediaPlayer Singleton

查看:95
本文介绍了如何使用MediaPlayer Singleton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Android开发的新手,并且从一个简单的音板应用程序开始.我开始使用多个片段开发音板,直到意识到自己正在使用MediaPlayer的多个实例.这不好,因为我一次只想播放一种声音.

I am new to Android developing and am starting with a simple soundboard application. I started developing a soundboard using multiple fragments until I realized that I was using multiple instances of MediaPlayer. This is not good because I want only one sound to play at a time.

我意识到我必须使用MediaPlayer Singleton来解决我的问题.唯一的问题是,我在网上找不到许多MediaPlayer Singleton的资源或示例.

I realized that I'd have to use a MediaPlayer Singleton to solve my problem. The only problem is that I can't find many sources or examples of the MediaPlayer Singleton online.

这是我最初放入每个片段中每个"onCreateView"中的内容:

Here's what I originally put into every "onCreateView" in each fragment:

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类中.我不知道该怎么办.

To my knowledge I'd probably put the onClickListener inside of each fragment and the MediaPlayer Singleton in a new Java class. I don't know what to do from there though.

如何实现MediaPlayer Singleton,以及如何在片段的"onCreateView"方法中调用它?

How do I implement a MediaPlayer Singleton and how do I call it back in the fragment's "onCreateView" method?

高度赞赏示例并表示感谢!

Examples are highly appreciated and thanks!

推荐答案

看,Singleton是一种设计模式,它是通过将默认构造函数设置为private来实现的,那么您应该提供一种get方法,以便您可以恢复自己的对象实例.看看下面的例子:

See, Singleton is a design pattern, and it is implemented by setting the default constructor as private, then you should provide a get method from wich you can recover your object instance. Check out the example bellow:

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的每个片段中,可以绑定服务并使用定义的接口.在下面的课程中看看:

In your sittuation, the best thing to do is to create a Service class that will encapsulate all the MediaPlayer methods. This is done like that because, usually, the developer wants that the player keeps playing even if the user leaves the Activity to which it is binded. In each fragment that you want to use the MediaPlayer API, you can bind the Service and use the defined interface. Take a look in the class below:

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元素.观察者非常适合这种情况.

I highly recommend that you follow this strategy of creating a MusicPlayer service. Also, I suggest you to take a look in another Design Patter called Observer. Usually, in music apps, you want to update several UI elements based on the MP state. Observer is perfect for that situation.

希望我有所帮助.

这篇关于如何使用MediaPlayer Singleton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆