Service 簡單的音樂播放服務

關於Service必須要知道的:

Service沒有可視化界面,是一個後臺運行的組件,用來執行不需要與用戶交互的任務。服務的兩種狀態:

Started: 如果Service通過startService()來啓動服務,則服務會進入Started狀態,一旦服務啓動後,可以在後臺無限期運行,和啓動服務的應用沒有了直接關係。

Bound:當應用通過bindService()綁定服務,則服務進入Bound狀態。Bound狀態的服務會提供一個藉口來允許組件與服務進行交互。

兩種不同啓動方式的服務的生命週期,圖片來自Android官網:


左面爲通過startService創建服務生命週期,右圖爲bindServiece創建服務的生命週期。

下面開始創建簡單的音樂播放服務:

簡單的佈局,代碼就不貼了:


然後在res目錄下新建一個raw目錄,隨便把一個音樂文件複製進去:


創建一個自定義服務類,繼承Service,重寫它的onCreate,onStart,onDestroy,onBind,和onUnbind方法:

/**  * Created by Administrator on 2017/5/8 0008.  */  public class MusicService extends Service {
    MediaPlayer mediaPlayer;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("Music","onBind");
        mediaPlayer.start();
        return null;
    }
    @Override
    public void onCreate() {
        Log.e("Music","onCreate");
        mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.beijiaerhupan);
        mediaPlayer.setLooping(true);
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Music","onStart");
        mediaPlayer.start();
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        Log.e("Music","onDestroy");
        mediaPlayer.stop();
        super.onDestroy();
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("Music","onUnBind");
        mediaPlayer.stop();
        return super.onUnbind(intent);
    }
}
在各個方法裏打印日誌以便觀察。其中onStart方法已經棄用,我們重寫了它的onStartCommand方法。

在MainActivity中,寫下以下代碼:

public class MainActivity extends AppCompatActivity {
    Intent intent;
    ServiceConnection conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this,MusicService.class);
        //服務連接對象
        conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e("MainActivity","connected");
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.e("MainActivity","disconnected");
            }
        };
    }
    public void startMusic(View v){
        startService(intent);
    }
    public void stopMusic(View v){
        stopService(intent);
    }
    public void bindMusic(View v){
        bindService(intent,conn, Context.BIND_AUTO_CREATE);
    }
    public void unbindMusic(View v){
        unbindService(conn);
    }

最後記得要在清單文件中註冊!

<service android:name=".MusicService"/>

然後運行程序,第一次我們點擊「開啓播放服務」,然後再點擊「停止播放服務」,可以看到打印的日誌:


然後我們點擊「開啓播放服務」,然後再把應用銷燬,日誌:



當應用終止以後,其實又重新的調用了一遍onCreate和onStart,然後音樂一直不停地播放下去了。

當點擊「綁定服務」,然後點擊「解除綁定服務」時,日誌:


點擊「綁定服務」,然後銷燬應用程序:


這裏跟網上有些出入,雖然應用退出以後音樂也不在播放,但是Service並沒有調用unbind和destroy方法。

不過後來發現,沒有調用unbind和destroy是因爲我把程序強行銷燬了,並沒有點後退鍵退出。又用後退鍵退出應用,則會正常調用unbind和ondestroy方法