首先我们先来看看怎么使用Service,然后再谈Android Service的内部机制。
在Android中Service的启动方式有两种,今天先发第一种。
Service的启动方式一:
启动:Context.startService(new Intent(context,xxx.class));
停止:Context.stopService() ;
我画了一个Service启动的流程图,相信大家一看就懂。Activity通过 Intent启动Service,如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果 Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 调用stopService就会触发Service的onDestroy()方法。

这一节里面傻蛋做了一个示例程序是一个音乐播放器,界面如下,功能很简单:播放、暂停、停止音乐、关闭Activity(这时Service仍然运行,继续播放音乐)、退出程序(停止音乐退出Activity)。

由于要控制Service的动作,傻蛋写了一个播放的通用类,这样在以后的课程中还能用上,代码如下:
/**
* MyMediaController.java
* com.androidtest.service.mediaplayer
*
* Function: TODO
*
* ver date author
* ──────────────────────────────────
* 2011-5-16 Leon
*
* Copyright (c) 2011, 最牛网 All Rights Reserved.
*/
package com.zuiniuwang;
import java.io.Serializable;
import android.media.MediaPlayer;
/**
* ClassName:MyMediaController
* Function: Mediaplayer 的一个控制类,控制播放器的播放 暂停 停止 等动作
* REASON
*
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-5-16
*/
public enum MyMediaController implements Serializable {
play {
@Override
public void execute() {
if (mediaPlayer != null && !mediaPlayer.isPlaying())
mediaPlayer.start();
// TODO Auto-generated method stub
}
},
pause {
@Override
public void execute() {
// TODO Auto-generated method stub
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
},
stop {
@Override
public void execute() {
// TODO Auto-generated method stub
if (mediaPlayer != null) {
mediaPlayer.stop();
try {
// 在stop后如果要重新Start需要prepare一下
mediaPlayer.prepare();
// 从头播放
mediaPlayer.seekTo(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
public static MediaPlayer mediaPlayer;
public abstract void execute();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
然后是控制播放的Activity:
/**
* MusicPlayer.java
* com.androidtest.activity
*
* Function: TODO
*
* ver date author
* ──────────────────────────────────
* 2011-5-15 Leon
*
* Copyright (c) 2011, 最牛网 All Rights Reserved.
*/
package com.androidtest.activity.musicplayer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.androidtest.MyImageButton;
import com.androidtest.R;
import com.androidtest.service.mediaplayer.MyMediaController;
import com.androidtest.service.mediaplayer.NormalMusicService;
import com.androidtest.sharedpreferences.TestSharePreferences;
/**
* ClassName:MusicPlayer Function: TODO ADD FUNCTION Reason: TODO ADD REASON
*
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-5-15
*/
public class NormalMusicPlayerActivity extends Activity implements OnClickListener {
private static final String TAG = NormalMusicPlayerActivity.class.getSimpleName();
private Intent intent ;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.music_player_layout);
Button playButton = (Button) this.findViewById(R.id.play);
playButton.setOnClickListener(this);
Button pauseButton =(Button) this.findViewById(R.id.pause);
pauseButton.setOnClickListener(this);
Button stopButton =(Button)this.findViewById(R.id.stop);
stopButton.setOnClickListener(this);
Button closeActivityButton =(Button)this.findViewById(R.id.close);
closeActivityButton.setOnClickListener(this);
Button exitActivityButton =(Button)this.findViewById(R.id.exit);
exitActivityButton.setOnClickListener(this);
intent = new Intent("com.androidtest.service.mediaplayer.NormalMusicService");
TestSharePreferences testSharePreferences=(TestSharePreferences)this.getApplication();
Log.v(TAG , ""+testSharePreferences.getSharedInteger());
}
private void playAction(MyMediaController playType) {
Bundle bundle = new Bundle();
bundle.putSerializable(NormalMusicService.INTENT_KEY, playType);
intent.putExtras(bundle);
NormalMusicPlayerActivity.this.startService(intent);
}
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch (view.getId()) {
case R.id.play:
Log.d(TAG, "play.......");
playAction(MyMediaController.play);
break;
case R.id.pause:
Log.d(TAG, "pause.......");
playAction(MyMediaController.pause);
break;
case R.id.stop:
Log.d(TAG, "stop.......");
playAction(MyMediaController.stop);
break;
case R.id.close:
Log.d(TAG, "close.......");
this.finish();
break;
case R.id.exit:
Log.d(TAG, "exit.......");
stopService(intent);
this.finish();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
最后是Service类
/**
* MusicService.java
* com.androidtest.service
*
* Function: TODO
*
* ver date author
* ──────────────────────────────────
* 2011-5-15 Leon
*
* Copyright (c) 2011, 最牛网 All Rights Reserved.
*/
package com.zuiniuwang.service;
import java.io.Serializable;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import com.zuiniuwang.*;
/**
* ClassName:MusicService
* Function: TODO ADD FUNCTION
* Reason: TODO ADD REASON
*
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-5-15
*/
public class NormalMusicService extends Service{
private String TAG = NormalMusicService.class.getSimpleName();
private MediaPlayer myMediaPlayer ;
public static final String INTENT_KEY= "action" ;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v(TAG , TAG+ " onCreate()");
super.onCreate();
if(myMediaPlayer==null){
myMediaPlayer=MediaPlayer.create(this, R.raw.test) ;
myMediaPlayer.setLooping(false);
}
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
Log.v(TAG , TAG + " onStart()");
super.onStart(intent, startId);
if(intent!=null){
MyMediaController mediaControl =(MyMediaController)intent.getSerializableExtra(NormalMusicService.INTENT_KEY);
mediaControl.mediaPlayer=myMediaPlayer;
mediaControl.execute();
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.v(TAG , " onDestroy");
if(myMediaPlayer!=null){
myMediaPlayer.stop();
myMediaPlayer.release();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
附件为本实例的代码下载地址:http://down.51cto.com/data/326354