Service:是一个可以在后台执行长时间运行操作而不使用用户界面的Android应用组件。启动Service有两种方式:startServie和bindService。通过startService开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在 。通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 (若该service仅与该调用者绑定,那么该调用者被销毁,那么该service也被销毁;若该service与多个调用者绑定,那么当所有调用者与该service解除绑定,该service被销毁)。
一、startService的方式启动Service,其生命周期为:onCreate–>onStartCommand(android2.0以前,为onStart)–>onDestroy.
下面为利用Service播放音乐的demo
MainActivity的xml文件,里面有播放音乐、停止播放和停止服务三个按钮
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/play_musi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="开始播放" />
<Button
android:id="@+id/stop_music"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="停止播放播放" />
<Button
android:id="@+id/stop_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="停止服务" />
</LinearLayout>
MainActivity Java文件,当多次调用startService,Service的onCreate方法只会被调用一次,onStartCommand方法被多次调用,所以在onStartCommand实现播发和停止播放音乐的逻辑
package com.example.servicetest;
import android.R.integer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button play_music = (Button) findViewById(R.id.play_musi);
Button stop_music = (Button) findViewById(R.id.stop_music);
Button stop_service = (Button) findViewById(R.id.stop_service);
intent = new Intent();
intent.setClass(this, MusicService.class);
play_music.setOnClickListener(this);
stop_music.setOnClickListener(this);
stop_service.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play_musi:
LogUtil.d("播放音乐");
intent.putExtra("msg", 0);
intent.putExtra("musicName", "music.mp3");
startService(intent);
break;
case R.id.stop_music:
LogUtil.d("停止播放音乐");
intent.putExtra("msg", 1);
startService(intent);
break;
case R.id.stop_service:
LogUtil.d("停止服务");
stopService(intent);
break;
default:
break;
}
}
}
用于播放音乐的Service
package com.example.servicetest;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.IBinder;
public class MusicService extends Service {
private MediaPlayer mediaPlayer; // 媒体播放器对象
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
LogUtil.d("onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int msg = intent.getIntExtra("msg", -1);
String musicName = intent.getStringExtra("musicName");
LogUtil.d("onStartCommand" + "msg: " + msg + " musicName: " + musicName);
if (msg == 0) {
play(musicName);
}
if (msg == 1) {
stop();
}
return super.onStartCommand(intent, flags, startId);
}
private void play(String musicName) {
try {
LogUtil.d("play");
mediaPlayer.reset();// 把各项参数恢复到初始状态
AssetFileDescriptor fileDescriptor = getAssets()
.openFd(musicName);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
fileDescriptor.getStartOffset(),
fileDescriptor.getLength());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
LogUtil.d("播放失败:" + e.getMessage());
e.printStackTrace();
}
}
private void stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
LogUtil.d("stop");
}
}
@Override
public void onDestroy() {
LogUtil.d("onDestroy");
stop();
mediaPlayer = null;
super.onDestroy();
}}
二、bindService的方式启动Service,其生命周期为:onCreate–>onBind–>Service运行–>调用者unbindService或调用者被销毁–>–>onUnbind–>onDestroy.Service中还有一个onRebind方法,那么它何时被调用呢?如果调用者同时startService和bindService,当调用者和service解除绑定后,并且onUnbind返回为true(默认情况下,onUnbind方法返回return super.onUnbind(intent);而super.onUnbind(intent)为false,所以要手动返回为true),当调用者再次绑定Service时,onRebind会被调用。
以下bindService的demo中,MyService继承于Service,有个继承于Binder的内部类,并定义了MyServiBce方法,目的是通过MyBinder返回MyService的实例。
package com.example.bindservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service{
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
LogUtil.d("onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogUtil.d("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
LogUtil.d("onUnbind");
boolean re = super.onUnbind(intent);
LogUtil.d("onUnbind默认返回: " + re);
//return super.onUnbind(intent);
return true;
}
@Override
public void onRebind(Intent intent) {
LogUtil.d("onRebind");
super.onRebind(intent);
}
@Override
public IBinder onBind(Intent arg0) {
LogUtil.d("onBind");
return mBinder;
}
public class MyBinder extends Binder{
public MyService getService(){
//返回serive实例
return MyService.this;
}
}
public int sum(int a,int b){
return a + b;
}
@Override
public void onDestroy() {
LogUtil.d("onDestroy");
super.onDestroy();
}
}
MainActivity的java文件,其通过ServiceConnection和Service通信,如调用Service中的sum方法
package com.example.bindservice;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void bindMyService(View v) {
LogUtil.d("绑定服务");
Intent intent = new Intent();
intent.setClass(this, MyService.class);
//startService(intent);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
public void unbindMyService(View v) {
LogUtil.d("解除绑定服务");
unbindService(conn);
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
MyService myService = ((MyService.MyBinder) binder).getService();
int sum = myService.sum(1, 2);
LogUtil.d("和: " + sum);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
}