一、创建服务的原因
1.Activity中创建了线程,客户端被销毁了以后,线程仍然存在,其他Activity无法控制该线程
2.例如音乐服务创建以后,不同客户端可以通过绑定的方式访问该服务
二、服务的分类
1.startService(Intent)
内部又分为继承IntentService 与继承service。前者一次执行一次请求,执行完毕即删除服务,鸟用没有;后着可以同时处理多个请求,处理请求完毕后最好自己添加上去stopSelf()方法,也可以Activity中调用stopService(Intent)方法。
后着服务启动的时候,调用onStartCommand(Intent ,int,int startId)方法,当服务销毁的时候,会调用onDestroy()方法。
2.bindService(Intent,ServiceConnection,BIND_AUTO_CREATE)
分为继承Binder与传递Message的方法,前者私有应用程序使用,后者不同应用程序使用。这里就说前者。
服务启动的时候不调用onStartCommand(Intent ,int,int startId)方法了,只调用onBind(Intent)方法返回一个Binder的派生对象。服务销毁的时候,会调用onDestroy()方法。
注意事项:
1.服务类的内部回调方法的重写,全都是public,这与Activity的protected不同,书写注意下。
2.诺同时以两种方式启动,则分别调用二者的销毁服务方法是没用的,必须同时调用才能杀死服务。前者没调用时服务的started=true,调用后变为false
3.以绑定的方式启动,这个操作时异步的,需要等待一两秒才传回来一个IBinder对象,所以在绑定操作的后面开个线程等个一两秒在操作服务内的方法是不错的选择。
代码案例:(完整的音乐播放服务)
1.服务的创建
public class CurrentTimeService extends Service {
private Thread thread; // 声明一个线程对象
private static MediaPlayer mp = null; // 声明一个MediaPlayer对象
private final IBinder binder = new LocalBinder();
@Override
public void onCreate() {
super.onCreate();
Log.i("test1", "onCreate被调用了");
}
@Override
public IBinder onBind(Intent arg0) {
return binder;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("test1", "onStartCommand被调用了");
return START_STICKY;
}
@Override
public void onDestroy() {
Log.i("test1", "onDestroy被调用了");
if(mp!=null){
mp.release();
mp=null;
thread.interrupt();
}
}
public class LocalBinder extends Binder {
CurrentTimeService getService() {
return CurrentTimeService.this;// 返回当前服务的实例
}
}
public void getCurrentTime() {
thread = new Thread(new Runnable() {
@Override
public void run() {
try{
if(!Thread.currentThread().isInterrupted()){
playBGSound(); // 播放背景音乐
}else{
return;
}
}catch(Exception e){
e.printStackTrace();
}
}
});
thread.start(); // 开启线程
}
// 播放背景音乐
private void playBGSound() {
if (mp != null) {
mp.release(); // 释放资源
}
mp = MediaPlayer.create(CurrentTimeService.this, R.raw.music);
mp.start(); // 开始播放
}
}
2.调用服务的Activity的创建
public class DetailActivity extends Activity {
CurrentTimeService cts;
boolean bound;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detail);
Button button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Button button4=(Button)findViewById(R.id.button4);
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onStopp();
}
});
Button button5=(Button)findViewById(R.id.button5);
button5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cts.getCurrentTime();/*判断cts这个客户端的服务有么有被删除.结论是不会随着服务的销毁而 销毁,它的生命伴随该Activity*/
}
});
Button button7=(Button)findViewById(R.id.button7);
button7.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DetailActivity.this, TestActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
Button button1=(Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DetailActivity.this, CurrentTimeService.class);
startService(intent);
bindService(intent, sc, BIND_AUTO_CREATE);// 绑定服务
new Thread(new Runnable(){
@Override
public void run(){
try{
Thread.currentThread().sleep(2000);
cts.getCurrentTime();
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
});
}
public void onStopp(){
if (bound) {
Intent intent = new Intent(DetailActivity.this, CurrentTimeService.class);
unbindService(sc);/* 解绑 ,解绑以后started=false,服务仍然存在,没有调用onDestroy()这个方法*/
stopService(intent);/*光解绑没用,服务的状态还是started=true*/
}
}
@Override
protected void onStop() {
super.onStop();
}
private ServiceConnection sc = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
bound = false;
Log.i("test1", "没有绑定");
}
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;/*获得自定义的LocalBinder对象*/
cts = binder.getService();/*获得CurrentTimeService对象*/
bound = true;
Log.i("test1", "绑定");
}
};
}
3.查看服务的Activity的创建
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onStart() {
super.onStart();
StringBuilder serviceInfo = new StringBuilder();
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningServiceInfo> services = manager.getRunningServices(100);// 获得正在运行的服务列表
for (Iterator<RunningServiceInfo> it = services.iterator(); it.hasNext();) {
RunningServiceInfo info = it.next();
// 获得一个服务的详细信息并保存到StringBuilder
if((info.process.equals("com.example.androidservier"))){
serviceInfo.append("process: " + info.process + "\n");
serviceInfo.append("service: " + info.service + "\n");
serviceInfo.append("started: " + info.started + "\n");
serviceInfo.append("\n");
}
}
ScrollView scrollView = new ScrollView(this);// 创建滚动视图
TextView textView = new TextView(this);// 创建文本视图
textView.setBackgroundColor(Color.BLACK);// 设置文本颜色
textView.setTextSize(25);// 设置字体大小
textView.setText(serviceInfo.toString());// 设置文本内容
scrollView.addView(textView);// 将文本视图增加到滚动视图
setContentView(scrollView);// 显示滚动视图
}
private static String formatData(long data) {// 用于格式化时间
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date(data));
}
}