Service简析
2016-07-11 19:47
621 查看
简介
Service作为Android的四大组件之一,它的重要性不言而喻,之前虽说看过一些介绍但是一直没有用过,最近需要用到的时候发现无从下手,便阅读了官方的有关Service的Guide,这里总结一下。Service作用
官方介绍如下A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
Service主要用于在后台执行长期任务或者耗时操作,在需要的时候甚至可以在应用退出的时候保持运行状态。
Service与Thread
虽说Service可以在后台执行任务,但是实际上一个Service是运行在主线程的,如果有耗时操作我们必须在Service中自己开启一个Thread避免ANR。那就会有这么一个问题,我们为什么不用Thread呢?主要的原因就是Thread的可控性不好,假设我们在一个Activity中启动了一个Thread,一旦这个Activity结束了,那么其他的Activity就没有办法拿到这个Thread的引用,更别谈控制了。可是Service不一样,一个Service整个程序只会创建一个实例,而且任何Activity都可以控制,那么Service里的Thread就可以由所有Activity控制了。而且Service作为四大组件之一,有较高级别,在后台运行不容易被系统杀掉。Service分类
Service分为两类Started Service:不和其他组件通信
Bound Service:可以和其他组件通信
无论使用哪一种Service都必须重写onBind()方法,如果使用Started Service返回null就可以了。
使用Started Service
一般需要再重写两个方法onCreate():启动Service的时候并不存在该Service实例,就会调用该方法。
onStartCommand(Intent intent, int flags, int startId):每次通过startService(Intent intent)启动的时候就会掉用该方法,一般在这里开启新线程。
onStartCommand(Intent intent, int flags, int startId)方法返回int类型的值,代表Service被kill后的行为,有以下三种:
START_NOT_STICKY:表示不重新创建
START_STICKY:表示重新创建,调用onStartCommand传入null
START_REDELIVER_INTENT:表示重建,调用onStartCommand传入上一个Intent
为了节省资源和电量,我们在任务结束后必须关闭Service,想要关闭Service可以通过本身调用stopSelf()或者其他组件调用stopService(),但是如果我们的Service处理多个onStartCommand请求的时候,我们在请求结束后掉用stopSelf()可能会打断已经收到的新的请求,最好的情况就是我们本身就是最后一个请求,stopSelt(int)的一个参数的重载可以解决这个方法,传入的id就是onStartCommand传递进来的id,代表当前任务的id,它会把传入的id和最后一个id比较,如果一样的话就代表本身是最后一个任务,就会stop掉,否则不会执行stop。
使用Bound Service
主要和Started Service的区别就是可以和其他组件通信,通过Binder。创建时必须定义接口描述用户如何与Server交流,接口必须继承Binder。使用bindService()创建,必须提供一个ServiceConnection的实现,,bindService()是一个异步方法,立马回返回。当创建完后会调用ServiceConnection的onServiceConnected,并传递binder通信。onBind方法只在第一个用户连接调用,后来都返回同一个binder(因为只会有一个Service),代码如下
public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /** method for clients */ public int getRandomNumber() { return mGenerator.nextInt(100); }
bind service的代码如下
private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } };
bindService(intent, mConnection, 0);
可以看出我们在Service中自定义了binder继承自Binder,并声明了一个方法,然后在onBind()中返回一个实例。我们会在onServiceConnected方法中得到这个binder,然后我们调用里的方法得到Service的实例,这样就可以掉用里面方法了,也就完成了通信。bindServicer第三个参数是刚开始的选择,如果是BIND_AUTO_CREATE表示如果没启动就新建
注意事项
onServiceDisconnected方法不是unbind的时候调用的,实在被kill等意外情况调用的相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories