Service作为Android四大组件之一,虽然不常使用到,但是还是需要有一定的了解。今天重看Service,需要把一些知识点记录下来,将来忘记时可以回看。
Service有启动状态,也有绑定状态。
启动状态
生命周期:startService -> onCreate -> onStartCommand -> onDestroy。
这种方式启动的Service,启动完成之后,Service脱离调用组件的管理,进行自己的操作,不会给调用方返回任何结果。如果需要停止Service,则调用方组件调用stopService方法。如果调用方组件没有手动调用停止Service的方法,即时调用方组件被销毁之后,Service也会继续执行。
//Activity
startServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService();
}
});
stopServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService();
}
});
private void startService(){
startService(new Intent(this,MyService.class));
}
private void stopService(){
stopService(new Intent(this,MyService.class));
}
//Service
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: do some work");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
绑定状态
生命周期:bingService() -> onCreate -> onBind -> onUnBind -> onDestroy。
这种方式是通过绑定Service,从而能够比启动方式能更好的控制Service。在这中方式下,onBind方法会返回一个IBinder给调用方,这样的话,可以在Service中创建一个内部类,继承自Binder(IBinder的实现类),然后在这个类中提供一个方法,这个方法返回当前Service的对象。从而调用方组件就可以获得Service的引用。这样就可以调用Service的公共方法来实现一些操作。这种方法绑定的Service一个Service可以由多个组件同时绑定,在所有调用方被销毁之后,Service也会被销毁。bingService这种方式也可以实现进程间通信。
//Activity
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyBinderService.MyBinder) service;
myBinderService = myBinder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
myBinderService = null;
}
};
bindServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService();
}
});
getValueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (myBinderService != null){
Log.d(TAG, "get value onClick: "+myBinderService.getNum());
}
}
});
unbindServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unBindService();
}
});
//Service
public class MyBinderService extends Service {
private static final String TAG = "MyBinderService";
private MyBinder myBinder = new MyBinder();
public MyBinderService() {
}
public class MyBinder extends Binder{
public MyBinderService getService(){
Log.d(TAG, "getService: ");
return MyBinderService.this;
}
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate: ");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
if(intent!=null){
return myBinder;
}else{
return null;
}
}
public int getNum(){
Log.d(TAG, "getNum: ");
return 3;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind: ");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: ");
super.onDestroy();
}
}
Service是运行在主线程中的,不能进程耗时操作,当Service阻塞时间达到20秒(Activity是5秒,广播是10秒)的时候,就会出现ANR(Application Not Responding)。所以如果需要在Service中进行耗时操作(如网络请求),需要开启子线程来执行。