Service基本使用
Service是长时间驻留在Android中的一种后台服务, 主要用于消息处理, 跨进程之间的通信. 例如, 使用手机能够边播放音乐边使用其他应用就是因为音乐应用通过Service播放.
0x10 简介
Service有两种启动方式, 分别为Start
和bind
方式:
状态 | 描述 |
---|---|
Started | Android的应用程序组件,如活动,通过startService()启动了服务,则服务是Started状态。一旦启动,服务可以在后台无限期运行,即使启动它的组件已经被销毁。 |
Bound | 当Android的应用程序组件通过bindService()绑定了服务,则服务是Bound状态。Bound状态的服务提供了一个客户服务器接口来允许组件与服务进行交互,如发送请求,获取结果,甚至通过IPC来进行跨进程通信。 |
0x11 生命周期
0x12 回调方法
回调 | 描述 |
---|---|
onStartCommand() | 其他组件(如活动)通过调用startService()来请求启动服务时,系统调用该方法。如果你实现该方法,你有责任在工作完成时通过stopSelf()或者stopService()方法来停止服务。 |
onBind | 当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回IBinder对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回null。 |
onUnbind() | 当客户中断所有服务发布的特殊接口时,系统调用该方法。 |
onRebind() | 当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。 |
onCreate() | 当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装。 |
onDestroy() | 当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。 |
0x20 代码示例
定义一个ServiceDemo.class
类, 作为处理消息的主要类:
package com.killshadow.attackhms;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class ServiceDemo extends Service {
private static final String TAG = "ServiceDemo";
private int count;
private boolean start;
// 用于onBind的时候返回给客户端
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder {
public int getCount() {
return count;
}
}
// Service最开始启动的回调方法, 如果已经onCreate, 则bindService的时候直接onBind
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"ServiceDemo -> onCreate, Thread ID: " + Thread.currentThread().getId());
this.start = true;
// 创建一个线程动态修改count的值
new Thread() {
public void run() {
while (start) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 每秒加1
count++;
}
}
}.start();
}
// startService的时候回调用这个回调
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "ServiceDemo -> onStartCommand, startId: " + startId + ", Thread ID: " + Thread.currentThread().getId());
return START_STICKY;
}
// bindService的时候, 一定会调用这个回调
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "ServiceDemo -> onBind, Thread ID: " + Thread.currentThread().getId());
return binder;
}
// 当service被unBind之后, 再次bind的时候会调用这个回调
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.i(TAG, "ServiceDemo -> onRebind");
}
// 调用unbindService的时候会调用这个方法
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "ServiceDemo -> onUnbind");
return true;
}
// stopService会调用这个回调, 销毁service
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "ServiceDemo -> onDestroy, Thread ID: " + Thread.currentThread().getId());
this.start = false;
}
}
下面分别介绍两种启动Service的方法.
0x21 Started
Intent intent = new Intent(mContext, ServiceDemo.class);
// start-stop Service
startService(intent);
stopService(new Intent(mContext, ServiceDemo.class));
通过Start/Stop
方法开启/关闭Service
的方式比较简单, 发送intent
即可.
0x22 Bound
ServiceDemo.MyBinder myBinder;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Service Connected: " + name.getClassName());
myBinder = (ServiceDemo.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "Service DisConnected: " + name.getClassName());
}
};
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// unbind的时候检查count的值
Toast.makeText(mContext, "Count: " + myBinder.getCount(), Toast.LENGTH_SHORT).show();
unbindService(conn);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService(new Intent(mContext, ServiceDemo.class), conn, Service.BIND_AUTO_CREATE);
}
});