一、Service基本使用
Service是Android中实现程序后台运行的解决方案。
- 适用:长期需要执行,且不需要和用户交互的任务。
- 特点:服务的运行不依赖任何用户界面,即使程序被切换到后台,或者用户打开了另一个应用,服务仍可以正常运行。
- 注意:1,服务并不是运行在一个独立进程中,它依赖创建服务的进程。如果创建service的进程被杀掉,那么service也会被杀掉。2,service 不会自动开启线程,它所有的代码都是默认在主线程中运行,如果有耗时操作就需要我们自己在service开启线程,否则会堵塞主线程。
1,新建一个MyService
public class MyService extends Service {
private static final String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: 只会在Service创建的时候,调用");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: 服务启动的时候调用");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
2,启动 / 停止Service
//启动
Intent startServiceIntent = new Intent(this, MyService.class);
startService(startServiceIntent);
//停止(会调onDestory方法)
Intent stopServiceIntent = new Intent(this, MyService.class);
stopService(stopServiceIntent);
如果多次启动同一个Service,Service的onCreate方法只会调用一次,onStartCommand会调用多次。(测试如下图)
多次startService结果.png
二、活动与服务的通讯
Activity 和 service 通讯,需要使用到ServiceConnection,以及在Service中extends Binder的对象。
public class ServiceActivity extends BaseActivity {
private static final String TAG = "ServiceActivity";
@BindView(R.id.start_service_btn)
Button mStartServiceBtn;
@BindView(R.id.stop_service_btn)
Button mStopServiceBtn;
@BindView(R.id.bind_service_btn)
Button mBindServiceBtn;
@BindView(R.id.unbind_service_btn)
Button mUnbindServiceBtn;
MyService.MyBind mMyBind;
//匿名内部类创建
private ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected: 绑定的时候调用");
mMyBind = (MyService.MyBind) service;
mMyBind.doSomeThing();//调用Binder中的方法
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: 断开的时候调用");
}
};
@Override
public int getLayoutId() {
return R.layout.activity_service;
}
@Override
public void initView() {
}
@Override
public void initData() {
}
@OnClick({R.id.start_service_btn, R.id.stop_service_btn, R.id.bind_service_btn, R.id.unbind_service_btn})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.start_service_btn:
Intent startServiceIntent = new Intent(this, MyService.class);
startService(startServiceIntent);//开启服务
break;
case R.id.stop_service_btn:
Intent stopServiceIntent = new Intent(this, MyService.class);
stopService(stopServiceIntent);//停止服务
break;
case R.id.bind_service_btn:
Intent bindServiceIntent = new Intent(this, MyService.class);
bindService(bindServiceIntent, mServiceConnection, BIND_AUTO_CREATE);//绑定服务
break;
case R.id.unbind_service_btn:
Intent unbindServiceIntent = new Intent(this, MyService.class);
unbindService(mServiceConnection);//解绑服务
break;
}
}
}
class MyBind extends Binder {
public void doSomeThing() {
//这里只是测试方法
Log.d(TAG, "MyBind ---> doSomeThing: ----");
}
}
当调用了bindService()方法之后,Activity跟Service就会建立连接。此时就可以在ServiceConnection中的onServiceConnected()
里面获取到Binder,并调用相关方法从而实现了Activity调用Service中的方法,结果如下图。
绑定服务.png
当需要解绑的时候,调用unbindService()方法即可。
Service生命周期
startService 和bindService有些不同,这里将通过几种情况说明。下图可能更清晰。
Service在不同情况下的生命周期.png
1,调用startService() ----> stopService() Service生命周期如下图。
start - stop.png
2,调用bindService() ----> unBindService()
bind -- unbind.png
3,调用startService() --> bindService() -- >unbindService() --> stopService()
这种情况,如果想结束Service需要分别调用 unbindService 和stopService,才会执行onDestory方法。
启动解绑的情况.png
由此可以看出,service被以哪种方式启动,就需要那种方式去停止。














网友评论