1. 后台服务
后台服务分为可交互服务和不可交互服务。其区别在于启动服务的方式StartService()
和bindService()
。后者会返回Bind
对象供Service
中方法和处理结果,而前者不会。
1.1 不可交互服务
三个方法:
onCreate
,用于初始化服务,只会被调用一次。onStartService
,用于执行任务,每次调用Context.startService(context,Service.class)
都会调用。onDestory
,调用Context.stopService(context,Service.class)
结束服务的时候调用。
public class NoInterrationService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d("Service","onBind");
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("Service","onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service","onStartCommand");
new Thread(new Runnable() {
@Override
public void run() {
// 耗时操作
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.d("Service","onDestroy");
super.onDestroy();
}
}
##1.2 可交互服务
利用ConnectionService类和Service交互。
启动可交互服务bindService(new Intent(getApplicationContext(), InteractionService.class), connection, BIND_AUTO_CREATE);
。三个参数,intent
用于指定要启动的服务名称,ServiceConnection
用于交互,Flag
设置服务类型。
ServiceConnection :
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("Service", "onServiceConnected");
InteractionService.MyBinder binder = (InteractionService.MyBinder) service;
binder.func1();
unbindService(this); //关闭服务
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
public class InteractionService extends Service {
@Override
public void onCreate() {
super.onCreate();
Log.d("Service", "onCreate");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d("Service", "onBind");
return new MyBinder();
}
class MyBinder extends Binder {
public void func1() {
Log.d("Service", "func1");
Log.d("Service", "thread id " + Thread.currentThread().getId());
}
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("Service", "onUnBind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.d("Service", "onDestroy");
super.onDestroy();
}
}
从日志可见BindService并没有开启新的线程,但是有的时候我们 BindService
之后并没有调用Binder
中定义的func
。是因为开启服务是异步的,并不会立即执行ServiceConnection.onServiceConnected()
方法,我想内部实现应该是消息队列,将BindService
操作发送给主线程的Looper
,等待主线程处理这个消息的时候,再执行ServiceConnection.onServiceConnection
中的方法。
#2. 混合性交互的后台服务
或许你会迷惑,startService
和bindService
之间有什么关系?其实简单的说两者之间是没有关联的,类似于你亲妈生了个双胞胎一样。混合使用,其完整的生命周期是:onCreate->onStartCommand->onBind->onUnBind->onDestroy
。
3. 前台服务
由于后台服务优先级相对比较低,当系统出现内存不足的情况下,它就有可能会被回收掉,所以前台服务就是来弥补这个缺点的,它可以一直保持运行状态而不被系统回收。例如:墨迹天气在状态栏中的天气预报
4. IntentService
IntentService是专门用来解决Service中不能执行耗时操作这一问题的,创建一个IntentService也很简单,只要继承IntentService并覆写onHandlerIntent函数,在该函数中就可以执行耗时操作了。
IntentService的具体实现将在下一遍文章中介绍。
public class MyIntentService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// 处理耗时操作,已近开起来新的线程
}
}
5. 系统服务
系统服务提供了很多便捷服务,可以查询Wifi、网络状态、查询电量、查询音量、查询包名、查询Application信息等等等相关多的服务,具体大家可以自信查询文档,这里举例2个常见的服务。
Wifi
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
boolean enabled = wm.isWifiEnabled();
最大音量
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int max = am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);