本文目录
1 Service概述
1.1 后台运行
1.2 依赖应用程序
1.3 默认运行在主线程
2 startService启动
2.1 定义
2.2 启动顺序
2.3 例子
2.3.1 创建
2.3.2 声明
2.3.3 启动
3 bindService启动
3.1 定义
3.2 启动顺序
3.3 例子
3.3.1 创建自定义服务
3.3.2 声明
3.3.3 创建自定义服务的单例管理类
3.3.4 启动
1 Service概述
1.1 后台运行
Service是Android四大组件之一,它可以在后台执行长时间运行操作而没有用户界面的应用组件。
即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。
1.2 依赖应用程序
服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。
当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
1.3 默认运行在主线程
服务并不会自动开启线程,所有的代码都是默认运行在主线程当中的。
当我们要在服务里面执行一些阻塞操作(比如接收网络数据),就需要在服务的内部创建子线程,并在子线程里面执行具体的任务,否则就有可能出现主线程被阻塞住的情况。
因此也不可以在Service的onCreate里面做耗时操作,因为是在主线程(ActivityThread)中调用的,耗时操作会阻塞UI。
2 startService启动
Service的启动方式有两种:startService 和bindService,先来看startService方法。
2.1 定义
由其他组件调用startService()方法启动服务,启动它的组件(如Activity)和Service并没有关联。
当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。
因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。
2.2 启动顺序
- 第一次调用:构造方法 —> oncreate() —> onStartCommand()
- 第二次被调用:直接调用onStartCommand()
- 使用stopService() / stopSelf()结束: 调用 onDestory()
2.3 例子
2.3.1 创建
创建TestService.java继承自Service类,重写onCreate()方法、onStartCommand()方法、onBind()方法、onDestroy()方法,其代码如下:
public class TestService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2.3.2 声明
在AndroidManifest.xml文件中声明TestService组件,其代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http:///apk/res/android"
package="com.example.demo">
<application
...>
<activity
...>
<intent-filter>
...
</intent-filter>
</activity>
<service android:name=".service.TestService"/>
</application>
</manifest>
2.3.3 启动
在MainActivity里显式启动Service:
Intent intent = new Intent(MainActivity.this, TestService.class);
startService(intent);
3 bindService启动
3.1 定义
bindService方法启动Service,其他组件可以通过回调获取Service的代理对象和Service交互。
当启动方销毁时,Service也会自动进行unBind操作,绑定到service上面的组件可以有多个,当发现所有绑定都进行了unBind时才会销毁Service。即,当所有调用者都退出,服务也就终止。
3.2 启动顺序
- 使用bindService启动服务:构造方法 —> oncreate() —> onBind() —> onServiceConnected()
- 使用unbindService方法解除绑定时:onUnbind()
- 如果所有绑定都unBind: onDestory()
3.3 例子
3.3.1 创建自定义服务
创建TestService.java继承自Service类,重写onCreate()方法、onBind()方法、onUnbind()方法、onDestroy()方法 ,代码如下:
public class TestService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new TestServiceBinder();
}
@Override
public void onCreate() {
super.onCreate();
//初始化service
//...
}
public class TestServiceBinder extends Binder {
public TestService getService(){
return TestService.this;
}
}
}
3.3.2 声明
在AndroidManifest.xml文件中声明TestService组件,其代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http:///apk/res/android"
package="com.example.demo">
<application
...>
<activity
...>
<intent-filter>
...
</intent-filter>
</activity>
<service android:name=".service.TestService"/>
</application>
</manifest>
3.3.3 创建自定义服务的单例管理类
public class TestServiceManager {
private TestServiceManager () {
}
public static TestServiceManager getInstance() {
return TestServiceManager .SingletonHolder.instance;
}
private static class SingletonHolder {
private static TestServiceManager instance = new TestServiceManager ();
}
//开启服务
public void start(Activity activity){
Intent intent = new Intent(activity,TestService .class);
activity.bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
}
private TestService testService;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
testService = ((TestService.TestServiceBinder) service).getService();
//进行服务开启后的操作
//...
}
@Override
public void onServiceDisconnected(ComponentName name) {
testService = null;
}
};
}
3.3.4 启动
在apk的任何地方,通过管理类,可以启动服务。
TestServiceManager.getInstance().start(MainActivity.this);
下一篇文章,讨论Android8.0之后开启service出现的异常情况处理。