Service
什么叫Service?
Service其实就是Android运行在后台的一种看不见的任务,相当于一个没有界面的Activity。那么Activity和多线程又有什么区别呢?区别就在于Service一旦启动后没有让它停止,它就会一直运行在后台,不论你的应用是否退出,除非你关机重新开机。
Service的运用:
1、 继承Service类,重写方法:
public class MyService extends Service {
MediaPlayer mp;
MyBinder mb = new MyBinder();
// 当前正在播放的音乐资源ID
public int currentSourceId;
@Override
public IBinder onBind(Intent arg0) {
System.out.println("===onBind");
return mb;
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("===onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("===onDestroy");
release();
}
@Override
public void onStart(Intent intent, int startId) {
System.out.println("===onStart");
// 启动服务的时候如果有音乐资源ID的数据就播放该音乐
if (intent.getIntExtra("sourceId", 0) != 0) {
start(intent.getIntExtra("sourceId", 0));
}
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("===onUnbind");
return super.onUnbind(intent);
}
public class MyBinder extends Binder {
// 获得当前Service对象,这个在和Activity绑定的时候就可以利用这个还回的Service对象来控制Service里面的动作了
public MyService getService() {
return MyService.this;
}
}
/** 播放音乐 */
public void start(int sourceId) {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
currentSourceId = sourceId;
mp = MediaPlayer.create(this, currentSourceId);
mp.start();
}
/** 暂停音乐 */
public void pause() {
if (mp != null) {
if (mp.isPlaying()) {
mp.pause();
} else {
mp.start();
}
}
}
/** 关闭音乐 */
public void stop() {
if ((mp != null) && (mp.isPlaying())) {
mp.stop();
}
}
/** 释放资源 */
public void release() {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
mp = null;
}
}
}
2、 首先跟Receiver一样需要现在配置文件里面注册:
<service android:name=".MyService" >
<intent-filter>
<action android:name="TestService2_StartMusic" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
注册过程中要申明所感兴趣的消息。
3、 启动Service
Intent intent = new Intent();
intent.setAction("TestService2_StartMusic");Android_09_11Activity.this.startService(intent);
4、 停止Service
Intent intent = new Intent();
intent.setAction("TestService2_StartMusic");
Android_09_11Activity.this.stopService(intent);
通常的做法是将一个Activity和Service关联起来,这样子就可以用一个可控制的界面和后台的Service交互
一个服务只能运行一个实例,在绑定的过程中有两种情况:1.该服务已经在后台运行。 2.这个服务还没有开启。如果一个服务已经存在了当再次启动的时候只是执行onstart()方法并没有执行oncreate()方法,并且还保存了当前服务运行的状态。
绑定:
1.定义一个连接器:
// 连接器,当Activity和Service绑定的时候会调用该对象的方法
ServiceConnection sc = new ServiceConnection() {
// 连接失败时调用
public void onServiceDisconnected(ComponentName name) {
System.out.println("onServiceDisconnected");
}
// 连接成功
public void onServiceConnected(ComponentName name, IBinder binder) {
System.out.println("onServiceConnected");
// 得到自定义的MyService对象
ms = ((MyService.MyBinder) binder).getService();
// 根据MyService的currentSourceId变量来更新界面
switch (ms.currentSourceId) {
case 0:// MyService没有播放音乐
music1.setChecked(true);
selectedSourceId = R.raw.aaa;
break;
case R.raw.aaa:// MyService前面在播放第一首音乐
music1.setChecked(true);
selectedSourceId = R.raw.aaa;
if (ms.mp.isPlaying()) {
tv.setText("当前正在播放--->音乐aaa.mp3");
}
break;
case R.raw.bbb:// MyService前面在播放第二首音乐
music2.setChecked(true);
selectedSourceId = R.raw.bbb;
if (ms.mp.isPlaying()) {
tv.setText("当前正在播放--->音乐bbb.mp3");
}
break;
case R.raw.ccc:// MyService前面在播放第三首音乐
music3.setChecked(true);
selectedSourceId = R.raw.ccc;
if (ms.mp.isPlaying()) {
tv.setText("当前正在播放--->音乐ccc.ogg");
}
break;
}
}
};
2.用连接器去连接绑定Service
Intent intent = new Intent();
intent.setAction("TestService2_StartMusic");
// 绑定服务,如果服务没有开启就自动创建一个服务
this.bindService(intent, sc, Context.BIND_AUTO_CREATE);
3.解除绑定(这个通常放在Activity生命周期的ondestroy()里面执行,这样子解除和Activity的绑定就可以让Service继续在后台运行,否则Service和Activity的生命周期会一致)
this.unbindService(sc);
使用系统的Service:(使用某些系统服务的时候是要在配置文件里面添加权限的)
cm = (ClipboardManager) this
.getSystemService(Context.CLIPBOARD_SERVICE);
am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> list = am
.getRunningAppProcesses();
List<RunningTaskInfo> list2 = am.getRunningTasks(100);
System.out.println("当前正在运行的进程");
for (int i = 0; i < list.size(); i++) {
RunningAppProcessInfo rapi = list.get(i);
System.out.println(rapi.processName + "|"
+ rapi.toString());
}
System.out.println("当前正在运行的任务");
for (int i = 0; i < list2.size(); i++) {
RunningTaskInfo rapi = list2.get(i);
System.out.println(rapi.baseActivity.getClassName());
}