两种模式下的生命周期如下:(借用了Big不吃鱼的https://www.jianshu.com/p/4c798c91a613)
通过这种方式调用startService,onCreate只会被调用一次,多次调用startSercie会多次执行onStartCommand()和onStart()方法。如果外部没有调用stopService()或stopSelf()方法,service会一直运行。
示例:
public class AppService extends Service {
private static final String TAG ="AppService";
//多次调用startService只会调用一次onCreate方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate ,threadId ="+Thread.currentThread().getId());
}
//多次调用startService方法,会多次调用onStartCommand
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"onStartCommand startId ="+startId +", threadId ="+Thread.currentThread().getId());
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG,"onStart , threadId ="+Thread.currentThread().getId());
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"onBind.....");
return null;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"onUnbind.....");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy threadId ="+Thread.currentThread().getId());
}
}
在Activity中通过startService启动和销毁service
public class TestActivity extends Activity implements View.OnClickListener{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
}
@Override
public void onClick(View view) {
Intent intent = null;
switch (view.getId()){
case R.id.button1:
intent = new Intent(this,AppService.class);
startService(intent);
break;
case R.id.button2:
intent = new Intent(this,AppService.class);
stopService(intent);
break;
}
}
}
点击button1多次startService,然后点击button2销毁service,运行结果如下:
结论:多次调用startService只会产生一个service对象
当需要Activity Fragment与Service有交互操作时,一般选择bindService。通过IBinder接口获取Service对象,这样就可以调用Service中的方法,比如有些耗时的操作可以放在service中。
bindService方式下,service的生命周期与其绑定的组件(如Activity)相关联,如果组件调用了unbindService(),则Servcie会销毁,如果组件未调用该方法,则service随着其被绑定组件销毁而销毁。没有组件绑定service,它会自行销毁。
可以有一个或者多个组件绑定service。
第一步:首先在AppSercie中创建IBind接口,返回service实例。
private LocalBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public AppService getService(){
return AppService.this;
}
}
public IBinder onBind(Intent intent) { Log.i(TAG,"onBind....."); return mBinder; }
添加一个可以供外部调用的方法。
public void printSimpleTime(){
for (int i=0 ; i<10; i++){
try{
Thread.sleep(100);
Log.i(TAG,"i ="+i +",currentTime ="+System.currentTimeMillis());
}catch (InterruptedException e){
e.getStackTrace();
}
}
}
创建一个BaseActivity基类,添加bindService、unbindService方法
public class BaseActivity extends Activity {
protected AppService mService;
private ServiceConnection mServiceConnection;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void bindService(){
if (mServiceConnection==null){
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("AppService","onServiceConnected ------");
mService = ((AppService.LocalBinder) iBinder).getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("AppService","onServiceDisconnected =======");
mService = null;
}
};
}
bindService(new Intent(this,AppService.class),mServiceConnection, Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
}
public void unbindService(){
if (mServiceConnection!=null){
Log.i("AppService","unbindService =======");
unbindService(mServiceConnection);
mServiceConnection = null;
}
}
}
(注:bindService第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可)
然后再添加类继承BaseActivity,调用bindService(),获得service对象
public class BindServcieActivityA extends BaseActivity implements View.OnClickListener{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bindservice_a);
findViewById(R.id.bindButton).setOnClickListener(this);
findViewById(R.id.unbindButton).setOnClickListener(this);
findViewById(R.id.finishButton).setOnClickListener(this);
findViewById(R.id.optionButton).setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bindButton:
bindService();
break;
case R.id.unbindButton:
unbindService();
break;
case R.id.finishButton:
this.finish();
break;
case R.id.optionButton:
if (mService!=null){
mService.printSimpleTime();
}
break;
}
}
测试步骤:
1、点击bindButton,然后点击unbindButton,测试结果如下:
可以看出bindService的生命周期:
(1)当调用bindService时:onCreate -> onBind
BindServcieActivityA类中,ServiceConnection执行onServiceConnected()方法
(2)调用unbindService时,onUnbind ->onDestroy
2、bindService之后,直接finish()当前Activity,运行结果如下:
可以看到直接finish(),不会调用unbindService方法,Service在Activity销毁后,自行解除绑定然后销毁。
3、当调用bindService后,获取到AppService实例对象,通过对象调用AppServcie中的printSimpleTime()方法。(注:当调用unbindService方法时,不会调用onServiceDisonnected(),只有当Service的连接意外丢失才会用到这个方法,比如Service被强杀或崩溃)
4、用同样的方法创建一个BindServiceActivityB
public class BindServiceActivityB extends BaseActivity implements View.OnClickListener{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bindservice_b);
findViewById(R.id.bindBtn).setOnClickListener(this);
findViewById(R.id.unbindBtn).setOnClickListener(this);
findViewById(R.id.printBtn).setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
// bindService();
}
@Override
protected void onStop() {
super.onStop();
// unbindService();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bindBtn:
bindService();
break;
case R.id.unbindBtn:
unbindService();
break;
case R.id.printBtn:
if (mService!=null){
mService.printSimpleTime();
}
break;
}
}
}
测试步骤:
1)BindServiceActivityA先调用bindService()
2)跳转到BindServiceActivityB,依次调用bindServie(),printSimpleTime(),unbindService()
3)返回到BindServiceActivityA,调用unbindService()
step1:执行了Service的onCreate ->onBind,BindServcieActivityA执行onServiceConnected方法,获取了IBinder对象;
setp2:当前BindServcieActivityA已经与AppService建立绑定的情况下,BindServcieActivityB不会重新创建IBinder对象,直接调用onServiceConnected进行绑定,两者共享一个IBInder实例对象;调用unbindService(),解除了当前组件与Service的绑定关系。当Service没有与任何组件绑定的情况下,才会调用onUnbind方法。此时,BindServcieActivityA还在绑定连接中,所以不会执行Service的解绑方法。
step3:BindServcieActivityA调用unbindService(),执行onUnbind - >onDestroy