众所周知,Service会根据不同的启动方式,会有不同的生命周期的回调。startService和bindService的区别就是该service是否可以和启动它的组件(比如activity)通信,因为bindService可以拿到Service的binder,binder就是用来实现IPC!

一、onCreate

创建Service实例时被调用,但是这里的Service实例却和Activity的实例不太一样。Activity可以通过设置启动模式获取一个或多个实例,但Service不管设置2种启动模式的哪一种,都只会得到一个实例对象。毕竟Service是要与Activity交互的,没必要为每个“客户端”都单独设置一个“服务端”。在onCreate中我们做的,依旧是初始化,创建数据缓存、线程池等。

参考IntentService源码:

@Override
public void onCreate() {// TODO: It would be nice to have an option to hold a partial wakelock// during processing, and to have a static startService(Context, Intent)// method that would launch the service & hand off a wakelock.super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);
}

Service默认是在主线程中执行,除非要提高服务的优先级,防止应用进入后台时被kill。否则,最好创建新的线程、线程池,不要把一个后台任务放在Service主线程。

二、onStart

调用startService方法时调用的,我们的后台任务一般都会放在这里执行,你可以通过intent获取startService方法传递的参数,这里依然以IntentService为例看下它的实现方式:

@Override
public void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);
}

三、onBind

调用bindService方法时调用,如果使用bindService方式来启动服务的话,一般发生在Activity需要与Service进行通信的场景(比如说音乐播放器app里面就会用到),而Android的IPC主要是通过binder来实现的(也可以通过socket,在系统服务用的比较多),所以这里方法的返回值就需要一个binder实例。这里简单说下binder的实现机制,其实就是一套PC上的C/S模式,用户通过bindService接口获取到Service的代理,然后通过这个代理来跟Service通信。

public class MyService extends Service {Binder mService = new IMyAidlInterface.Stub() {@Overridepublic void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {}};public MyService() {}@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.return mService;}
}
// call in activity
bindService(new Intent(this, MyService.class), new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mServiceProxy = IMyAidlInterface.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {}
}, 0);

这里的代理包括:本地和远程代理两种,它们是按照service和activity是否在同一个进程中来区分的(这里仅以activity和service通信为例来说明,其他场景原理类似)。①如果是在同一进程,那么这个代理对象mServiceProxy其实就是mService对象。②而当它们不在同一个进程中时,mServiceProxy和mService就属于不同进程空间中的对象,由于不同进程之间的数据不能直接访问,所以这个时候binder driver就来充当一个中间桥梁的作用,来完成参数和返回结果等数据的传递(其实也就是在Linux内核空间开辟了一段共享内存),从而实现通信的目的。当然为了方便开发者使用binder,Android对binder的使用进行了一定的封装,提供了一个AIDL。通过AIDL我们就只需关心service提供的功能接口,而不用去关心这些接口调用的具体细节。

四、onRebind

在多次调用bindService和unbindService时会调用到该接口,一般不会在这do something,不过可能会有一些数据统计放在这里以观察用户的某一操作行为。

五、onUnbind

一般在Activity与Service断开连接时,调用UnbindService方法时调用。该接口默认返回false,如果要在onRebind中do something,需要使其返回true。

六、onDestroy

在Service销毁并释放onCreate中申请的资源时调用,参考IntentService实现:

@Override
public void onDestroy() {mServiceLooper.quit();
}

一般可以通过stopService或者unbindService(!通过startService启动Service)方式来销毁不再需要的Service。

Service VS 线程池

Android提供Service处理后台任务,但有的时候会实现一套线程池机制或者使用Android提供的AsyncTask来执行后台任务。

  • Service是Android系统提供的用来处理后台任务的组件,创建进程方便、使用方便、优先级高,可做一定程度的保活。但是多次IPC带来的效率不高问题也同样使人头大。
  • 线程池的运行效率高,配置和使用灵活。但是多进程实现不方便, 由于Android实现了一套进程托管机制,我们不能直接创建一个新的进程,而只能通过四大组件的形式创建新的进程。

Service应用场景分析相关推荐

  1. spring bean scope作用域及多线程安全问题场景分析

    2019独角兽企业重金招聘Python工程师标准>>> Scope作用域 在 Spring IoC 容器中具有以下几种作用域: singleton:单例模式,在整个Spring Io ...

  2. mysql表分区占用存储_MySQL 分区分表应用场景分析和分区中可能遇到的坑点

    MySQL的分区和分表应用场景分析 在日常工作中当我们的某张表的数据量过大的时候,首当其冲的可能就是进行分区和分表,但是是如何分区或者分表都要结合一点的业务场景下进行分析,才会显著的提升性能,来聊一聊 ...

  3. 如何调整按钮里的文字的位置android_UI设计中按钮场景分析

    别无他话,今天就和大家聊一聊设计宿敌--按钮设计.按钮的设计看似简单,其实按钮的功能不同,设计形式上也会有差异,今天我就针对按钮的场景分析,对按钮进行全面的解析. 按照功能性分类,按钮主要包括行为召唤 ...

  4. 电商抢购秒杀系统的设计_1_应用场景分析

    2019独角兽企业重金招聘Python工程师标准>>> 电商抢购秒杀系统的设计_1_应用场景分析 概述 所谓知已知彼,百战不殆,在开始详细介绍实战中的抢购秒杀系统时,我们了解一些抢购 ...

  5. mysql 事务 查询 范围加锁_MySQL死锁系列-常见加锁场景分析

    本文我们就从原理走向实战,分析常见 SQL 语句的加锁场景.了解了这几种场景,相信小伙伴们也能举一反三,灵活地分析真实开发过程中遇到的加锁问题. 如下图所示,数据库的隔离等级,SQL 语句和当前数据库 ...

  6. mysql常见死锁_MySQL死锁系列-常见加锁场景分析

    如下图所示,数据库的隔离等级,SQL 语句和当前数据库数据会共同影响该条 SQL 执行时数据库生成的锁模式,锁类型和锁数量. 下面,我们会首先讲解一下隔离等级.不同 SQL 语句 和 当前数据库数据对 ...

  7. 高并发编程-Daemon Thread的创建以及使用场景分析

    文章目录 官方文档 Daemon Thread VS User Thread Daemon thread的特点 方法 void setDaemon(boolean status) boolean is ...

  8. Ansible自动化运维企业实际应用场景分析

    企业实际应用场景分析 Dev开发环境 使用者:程序员 ​ 功能:程序员个人的办公电脑或项目的开发测试环境,部署开发软件,测试个人或项目整体的BUG的环境 ​ 管理者:程序员 测试环境 使用者:QA测试 ...

  9. shiro的会话管理:应用场景分析

    应用场景分析 在分布式系统或者微服务架构下,都是通过统一的认证中心进行用户认证.如果使用默认会话管理,用户信息只会保存到一台服务器上.那么其他服务就需要进行会话的同步. 会话管理器可以指定sessio ...

最新文章

  1. python线程,进程,协程
  2. ios遍历模块的方式
  3. 2021高考成绩查询省排名,重磅!2021全国各地高考预测分数线出炉,这样估分可以估算全省排名...
  4. 的文件夹结构_Windows中你需要知道的目录结构 「第一期」
  5. C#中Monitor和Lock的用法区别
  6. server sql 将出生日期转为年龄_在sql server表中有一个出生日期字段我怎么才能在当前年份改变时自动更新年龄字段...
  7. 一张纸能有多大力量?
  8. 2019蓝桥杯省赛---java---B---1(组队)
  9. linux简单好玩的命令,有趣的Linux命令行玩法 cal
  10. 计算机硬盘转速多少比较好,电脑硬盘的转速是什么意思?越快就越好么?
  11. ens32文件空白(没有ens33文件)
  12. 微信公众号开发之消息模板
  13. java达内小发猫课程,详细说明
  14. APP的文件数据直传腾讯云COS实践
  15. Centos7 升级 glibc 2.25
  16. 《侠盗猎车手-罪恶都市》秘籍
  17. 项目实施管理之项目调研
  18. 自然可视图是什么意思?
  19. flex 开源项目组件大全
  20. 详细实现yolov5测试丶自己数据集训练测试丶Tensorrt加速优化(完 结 !)+ 跟踪(补充)

热门文章

  1. Android EditText回车不换行
  2. Git命令集十五——拉取命令
  3. 使用openssl给web站点颁发证书
  4. 访客门禁系统供应商 首选钱林厂家
  5. Java记录 -24- equals方法重写
  6. HDU 1028 HDU Ignatius and the Princess III
  7. 【Vegas原创】outlook发送时,报550 5.7.1 client does not have permissions to send as this sender解决方法...
  8. [Markdown] 数学公式
  9. Linux文件系统2---VFS的四个主要对象
  10. Oracle E-Business Suite Maintenance Guide Release 12.2(Patching Utilities)