Service 作为 Android 四大组件之一, 可以与 Activity 建立双向连接(绑定模式), 提供数据和功能. 也能够接收 Intent 单方面请求(调用模式), 进行数据处理和调度功能.
Service 与 Activity 一样运行在主线程(UI 线程), 所以在 Service 中执行耗时操作, 可能会造成 Activity 不能及时响应用户的交互请求, 然后程序就被系统干掉啦.
个人看法 四大组件都是运行在主线程里面, 应该有一个消息循环在调度. 不同的操作, 不同的消息. 例开启一个 Service, 对应消息的处理, 可能是 new 一个 Service 然后调用 onCreate,onStartCommand 等. 一个消息处理完, 又返回消息循环处理下一个消息. 至于消息可以用队列存储.
生命周期
Service 只有在一开始创建实例的时候执行 onCreate, 后面所有的请求, 无论是调用模式还是绑定模式都是在该实例里面处理. Service 实例创建后只有两种销毁的方法, 系统回收或者显示执行了 stopService 方法. 在 Service 销毁的时候调用 onDestroy.
调用模式
通过 Context.startService 请求一个 Service 的方式, 称为调用模式. 该方式 Context 就打个招呼, 告诉 Service 该做事情了. Service 的实例收到请求就调用自己的 onStartCommand 方法.
1, 使用 Intent 确定请求的 Service, 然后 startService.
2,Service 主要是 onCreate 初始化, onStartCommand 执行动作, 或者发送一个开始的消息(Handler 机制).
代码
- import Android.App.Service;
- import Android.content.Intent;
- import Android.os.IBinder;
- import Android.util.Log;
- public class StickyService extends Service {
- private int callsum=0;
- public StickyService() {
- }
- @Override
- public void onCreate() {
- super.onCreate();
- callsum++;
- Log.d("StickyService","..............onCreate callSum="+callsum);
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- callsum++;
- Log.d("StickyService","..............onStartCommand callSum="+callsum);
- return START_STICKY;
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- callsum++;
- Log.d("StickyService","..............onDestroy callSum="+callsum);
- }
- @Override
- public IBinder onBind(Intent intent) {
- // TODO: Return the communication channel to the service.
- throw new UnsupportedOperationException("Not yet implemented");
- }
- }
为了验证 Service 一直只有一个实例, 用一个 int 变量 callSum 做访问统计. 结果如下.
onStartCommand 要求返回一个标志, 有三种标志 START_REDELIVER_INTENT,START_STICKY,START_NOT_STICKY. 三种标志代表的是系统在内存不足回收该 Service 之后不同的操作模式.
l START_STICKY 在回收之后, 一旦系统有充足的资源便要重新创建该 Service 的实例, 并且调用 onStartCommand,intent 为 null. 此模式除非显示调用 stopService, 不然它就 "不死".
l START_REDELIVER_INTENT 操作相同, 但是 intent 值为给 Service 收到的最后一个请求 intent. 这个模式关注的是每个 intent 的处理, 用来确保每个 intent 的请求都能完成.
l START_NOT_STICKY 说明系统可以无条件回收, 也不用重新创建 Service 的实例. 一般用于长期运行的 Service, 在 onStartCommand 中可以创建定时任务来唤醒自己.
绑定模式
在 Activity 和 Service 之间可以使用绑定模式. 调用 bindService, 发送一个 bind 请求. 如果 bind 成功, activity 可以获得 Service 一个内部类 (自己定义的) 的引用, 内部类可以访问 Service 所有的方法和属性. 这样就建立一个连接. 绑定模式不调用 onStartCommand, 调用 onBind, 解绑调用 onUnBind.
Service 代码
- import Android.App.Service;
- import Android.content.Intent;
- import Android.os.Binder;
- import Android.util.Log;
- public class BindService extends Service {
- public BindService() {
- }
- @Override
- public Binder onBind(Intent intent) {
- // TODO: Return the communication channel to the service.
- return new TBinder();
- }
- @Override
- public boolean onUnbind(Intent intent) {
- return false;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- Log.d("BindService",".................... onCreate");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d("BindService","....................onStartCommand");
- return START_NOT_STICKY;
- }
- // 创建一个 Binder 的子类. TBinder 是一个内部类, 可以访问 Service 的所有属性和方法.
- public class TBinder extends Binder {
- public String printServiceName(){
- return "BindService";
- }
- }
- }
Activity 代码
- void onBindSer(){
- Intent intent =new Intent(MainActivity.this,BindService.class);
- intentList.add(intent);
- /**
- * sc 为绑定成功或者失败之后的回调
- * flag=BIND_AUTO_CREATE 表示创建一个 Service
- */
- bindService(intent,sc,BIND_AUTO_CREATE);
- }
- // 创建服务绑定的回调接口对象
- ServiceConnection sc=new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- // 传入参数很明显了, 一个是组件名, 一个是 IBinder
- Log.d("MainActivity",componentName+"bind success");
- BindService.TBinder binder=(BindService.TBinder)iBinder;
- Log.d("MainActivity","serviceName ="+binder.printServiceName());
- }
- @Override
- public void onServiceDisconnected(ComponentName componentName) {
- Log.d("MainActivity",componentName+"bind failed");
- }
- };
日志输出
来源: http://www.bubuko.com/infodetail-2997979.html