前言
写着一篇文章的原因,主要是因为在面试中,服务这个关键词的出现频率非常高。很多时候,面试官会问你,Service中能否进行耗时操作?我们稍后就会揭晓那么这个答案。
作用:服务于需要长期运行的任务,比如资源下载、音视频播放等。
生命周期
生命周期图示由图中可以直观的看出几点。
启动方式 | 存在方式 |
---|---|
startService() | 独立于Activity运行,自行结束或被叫停 |
bindService() | 绑定于Activity运行,Activity结束时,会被叫停 |
涉及方法 | 用途 |
---|---|
onCreate() | |
onDestroy() | |
onStartCommand() | 用于计数,服务被调用的次数 |
onBind() | 与Activity组件绑定 |
onUnbind() | 与Activity组件解绑 |
使用方法
Service
方法需要在AndroidManifest.xml
中进行注册
// 第一步:启动
① startService(Intent);
② bindService(Intent, ServiceConnection, Int);
// 第二步:解绑(使用方法二启动时需要)
unBindService(ServiceConnection);
// 第三步:暂停
stopService(Intent);
Activity和Service的通信
Activity
和Service
的通信其实就是基于IBinder
来进行实现的。但是IBinder
其实是一个接口,对我们而言一般使用他的实现类Binder
并通过强制转换来完成操作。
/**
* Service方法继承
* onBind()是一个抽象方法。
*/
public class LocalService extends Service {
private final IBinder binder = new Binder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
protected class ServiceBinder extends Binder {
LocalService getLocalService(){
return LocalService.this;
}
}
}
以上代码,是一个用于通信的基础版本。
既然需要通信,那我们总需要知道对方是谁,如果使用的是startService()
,上文已经提到他是独立于Activity
的,所以势必使用的是bindService()
。
在上文的使用方法中已经提到了bindService()
使用到的参数,Intent
、ServiceConnection
、Int
。
ServiceConnection
在注释中已经比较清晰的写出了,代码的逻辑。
/**
* bindService()方法中的参数之一。
* 用于对service进行操作
*/
ServiceConnection connection = new ServiceConnection() {
// Activity和Service绑定时调用
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((LocalService.ServiceBinder)binder).getLocalService();
// 干你需要干的事情
}
// Activity和Service解绑时调用
@Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}
};
Int
-
BIND_AUTO_CREATE
:收到绑定需求,如果Service尚未创建,则立即创建。 -
BIND_DEBUG_UNBIND
:用于测试使用,对unbind调用不匹配的调试帮助。 -
BIND_NOT_FOREGROUND
:不允许此绑定将目标服务的进程提升到前台调度优先级
还有很多在
Service
类中
这是一个已经存在于Service
类中的值,这里并不全部例举,一般来说都是使用BIND_AUTO_CREATE
。
总结
- 在ANR机制中,
Service
的响应时长不能超过20s,其实也可以比较直观的看出,Service
其实并不能进行所谓耗时操作。但是如果加上了Thread
进行异步处理,那么其实他还是可以进行耗时操作的。(具体看你怎么进行回答,主要还是一个知识点,Service
运行在主线程) -
Service
存在的原因是Activity
是一个经常会被销毁的组件,虽然我们同样可以通过Thread
进行异步操作,但是当Activity
实例被销毁时,相应的捆绑在Activity
生命周期内的Thread
实例我们也没有能力再去寻找了。
以上就是我的学习成果,如果有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。
网友评论