前言:
本篇文章正经来说,其实算是我的学习履历,是我在不断的摸索过程中,总结的经验,不能算是一篇正经的学术文章。现在DELPHI的学习资料太少了,就算是有也都是基于老版本DELPHI,或VCL相关的内容,涉及FMX、Android编程就显得明显不足,我虽然也玩了几年的DELPHI,但说实话能力水平有限,下面的文章如果有错误的地方,也请同行的前辈们指点修正,先在此谢过。
那这篇文章主要说点什么呢,请大家先参考下面的目录,我尽可能把我知道的这点小经验分享给大家,这里面有很多的知识都是从网上学习整理而来,我也只是一个资料的整理者而已,考虑到DELPHI目前的学习资料匮乏问题,也为了照顾新人,在本文中先科普一些关键知识点,我会将内容尽可能讲到重点与详细说明,希望每个人都能看懂和理解。
提示:安卓系统的更新版本变化比较大,且国内各品牌手机系统都存在定制化问题,本文中所有涉及的实例程序,均是以DELPHI 11版本编写,如果其它DELPHI版本按照同方法出现问题,请大家自行修改,而测试的手机品牌主要以小米为主。
目录
一、Android Service简介
1.1 什么是Android Service?
本文中所写的Android Service是指运行于安卓系统后台的服务,主要的特点如下:
- 它运行于系统后台,没有界面,无法单独存在,必须要与前台程序绑定。
- 可长期运行,即使是前台的程序关闭或销毁,它依然可以运行于后台。
- 优先级高于Activity(内存不足时先杀掉Activity)。
- 运行在主线程,且不能做耗时操作(超时标准请参考下面的说明)
Activity:Activity是Android中四大组件之一,而我们的Android应用是由一个或多个Activity组成的。活动(Activity)是一个可视化的用户界面,负责创建一个屏幕窗口,放置 UI 组件,供用户交互。
安卓超时标准:Android中长时间无响应会出现ANR
- 后台Service:200秒(本文重点所讲内容)
- 前台Service:20秒(Foreground Service)后面有机会单独开一篇重点讲述
- Activity:5秒
- 后台广播:60秒
- 前台广播:10秒
ANR:(Application Not Responding)是指在安卓系统上,响应不够灵敏时,系统会向用户显示的一个对话框。
1.2 Android Service的生命周期
我们先用一张图来说明Android Service的生命周期,然后再来进行解释,图示如下:
从上图中我们可以看到,安卓服务有两种启动方式:StartService和BindService,下面针对这两种方式的生命周期,我们用两个表格来做简要说明,详细如下:
步骤 | 说明 |
---|---|
OnCreate() | 1、如果 service 没被创建过,调用 startService() 后会执行 onCreate() 回调; 2、如果 service 已处于运行中,调用 startService() 不会执行 onCreate() 方法。 |
onStartCommand() | 如果多次执行了 startService() 方法,那么 Service 的 onStartCommand() 方法也会相应的多次调用 |
OnBind() | Service中的onBind()方法是抽象方法,Service类本身就是抽象类,所以onBind()方法是必须重写的,即使我们用不到 |
onDestory() | 在销毁的时候会执行Service该方法 |
步骤 | 说明 |
---|---|
OnCreate() | 当服务通过 onStartCommand() 和 onBind() 被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装 |
OnBind() | 当其他组件想要通过 bindService() 来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回 IBinder 对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回 null |
onUnbind() | 当客户中断所有服务发布的特殊接口时,系统调用该方法 |
onRebind() | 当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法 |
onDestroy() | 当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等 |
提示:我们先只做理论上的说明,暂不涉及具体的实例与实现的方法,在后面的案例中,我们将用到前面所讲的理论知识点。
1.3 Android Service的类型与区别
在DELPHI中,我们创建Android Service时(创建方式如下图所示)软件提供了四种类型供我们选择,那么这四种Service程序到底有什么区别呢?
服务类型 | 区别 | 优点 | 缺点 |
---|---|---|---|
Local Service | 该服务依附在主进程上 | 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应BindService会方便很多 | 主进程被Kill后,服务便会终止 |
Intent Local Service | 同上 | 与上面的区别在于可以利用Intent处理异步请求 | |
Remote Service | 该服务是独立的进程 | 服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性 | 该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点 |
Intent Remote Service | 同上 | 与上面的区别在于可以利用Intent处理异步请求 |
- Intent:Intent用于Android程序中各组件(Activity、BroadcastReceive、Service)的交互,并且可以在组件之间传递数据。
- AIDL:Android Interface Definition Language是为了实现进程间通信而设计的Android接口语言
- IPC:Inter-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程
上面都是实现进程之间通讯的方式,详细内容太多,这里不详细说明,在后面的案例中,我们将会用到这些知识点。
1.4 Android Service能做什么?
- 网络事务:聊天(等待他人回复短信)、地图定位(熄屏后实时定位的播报语音)等
- 本地资源:播放音乐(读取音乐文件)、文件IO(后台上传文件、下载文件)等
- 定时任务:订单超时(未支付情况下,一定时间后自动销毁订单)、闹钟提醒等
小结:Android Service的简要知识点先介绍到这里,更多的内容或更详细的内容大家可以网上搜索,这里受篇幅问题,不过多介绍,下面我将按类型进行实例的演示介绍
二、Local Service程序
2.1 Local Service特点
如上面《表3:Android Service四种类型说明》所述,Local Service应该是使用最多的一种Service类型,其主要的特点如下:
- 运行在主进程上,并且与前台应用程序是同一个进程
- 与前台程序是一对一绑定,无法被其它程序调用
- 与前台程序的绑定不需要IPC或AIDL
2.2 Local Service实例
根据Local Service的特点,我们创建一个通知类的服务程序,由运行于后台的Service根据条件,给前台的程序进行通知的发送,本例设计主要实现以下几个功能:
- 如何创建一个Local Service服务
- 前台程序如何启动服务
- 后台如何发送通知给前台
- 如何获取安卓系统通知权限
- 如何确保锁屏或待机后仍然收到通知
说明:因为是第一个例子,所以在本例中有些公共的功能我会在此例中实现(如:权限申请,电源管理等),后面其它类型的案例我只针对差异性的地方进行案例说明
下面我们开始正式的案例编程:
后台Service编程:
首先,我们按照上面1.3所写的内容,创建一个Local Service的服务,然后在模块中放上一个NotificationCenter1控件,完成后所得到的界面如下图所示:
我们将工程与模块进行保存,这里有2个非常重要的地方要记住:
- 工程名字一定要记住,因为这涉及到前台程序调用的问题,我这里将工程名保存为:lSysService。