Android comprehensive failproof music service across multiple activities

前端 未结 3 1524
野的像风
野的像风 2020-12-24 02:17

I know this question has been asked many times before and might seem to be a conglomeration of several questions, but I feel that it is relevant and important to many develo

3条回答
  •  被撕碎了的回忆
    2020-12-24 02:47

    First here is some code. Below I'll give you an explanation.

    public class MusicService extends Service {
    
        // service binder
        private final IBinder mBinder = new LocalBinder();
    
        // music player controling game music
        private static CarefulMediaPlayer mPlayer = null;
    
        @Override
        public void onCreate() {
            // load music file and create player
            MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.title_music);
            mediaPlayer.setLooping(true);
            mPlayer = new CarefulMediaPlayer(mediaPlayer, this);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        // =========================
        // Player methods
        // =========================
        public void musicStart() {
            mPlayer.start();
        }
    
        public void musicStop() {
            mPlayer.stop();
        }
    
        public void musicPause() {
            mPlayer.pause();
        }
    
        /**
         * Class for clients to access. Because we know this service always runs in
         * the same process as its clients, we don't need to deal with IPC.
         */
        public class LocalBinder extends Binder {
            MusicService getService() {
                return MusicService.this;
            }
        }
    
        @Override
        public IBinder onBind(Intent arg0) {
            return mBinder;
        }
    
    }
    

    Activity:

    public class StartupActivity extends Activity {
    
    // bounded service
    private static MusicService mBoundService;
    
    // whetere service is bounded or not
    private boolean mIsBound;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_startup);
        doBindService();
    
        // HOW TO WORK WITH THE SERVICE:
        // call the following methods whenever
        // you want to interact with you 
        // music player
        // ===================================
    
        // call this e.g. in onPause() of your Activities
        StartupActivity.getService().musicPause();
    
        // call this e.g. in onStop() of your Activities
        StartupActivity.getService().musicStop();
    
        // call this e.g. in onResume() of your Activities
        StartupActivity.getService().musicStart();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        doUnbindService();
    }
    
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            setService(((MusicService.LocalBinder) service).getService());
        }
    
        @Override
        public void onServiceDisconnected(ComponentName className) {
            setService(null);
        }
    };
    
    private void doBindService() {
        Intent service = new Intent(getBaseContext(), MusicService.class);
        // start service and bound it
        startService(service);
        bindService(new Intent(this, MusicService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }
    
    private void doUnbindService() {
        if (mIsBound) {
            // Detach existing connection.
            unbindService(mServiceConnection);
            mIsBound = false;
        }
    }
    
    public static MusicService getService() {
        return mBoundService;
    }
    
    private static void setService(MusicService mBoundService) {
        StartupActivity.mBoundService = mBoundService;
    }
    }
    

    First of all you got a Service which runs in background. This service creates the mediaPlayer object as you did. With the localBinder you can bind the Service in your Activity(ies) and access it like a normal Java-Object. The Activity I've posted bindes the Service. In it's onCreate() method you can find a way how to interact with your mediaPlayer. You can bind any Activity to your Service.

    Another Solution:

    public class CarefulMediaPlayer {
    final SharedPreferences sp;
    final MediaPlayer mp;
    private boolean isPlaying = false;
    private static CarefulMediaPlayer instance;
    
    public CarefulMediaPlayer(final MediaPlayer mp, final MusicService ms) {
        sp = PreferenceManager.getDefaultSharedPreferences(ms.getApplicationContext());
        this.mp = mp;
        instance = this;
    }
    
    public static CarefulMediaPlayer getInstance() {
        return instance;
    }
    
    public void start() {
        if (sp.getBoolean("com.embed.candy.music", true) && !isPlaying) {
            mp.start();
            isPlaying = true;
        }
    }
    
    public void pause() {
        if (isPlaying) {
            mp.pause();
            isPlaying = false;
        }
    }
    
    public void stop() {
        isPlaying = false;
        try {
            mp.stop();
            mp.release();
        } catch (final Exception e) {}
    }
    }
    

    Then you can pause, play and stop the music by calling CarefulMediaPlayer.getInstance().play();

提交回复
热议问题