后台服务与广播

在安卓开发中,后台服务(Service) 是一种能够在后台运行的组件,它不与用户界面直接交互。即使用户的设备屏幕被锁住或切换到其他应用,服务仍然可以继续运行。

后台服务的作用及应用场景

  1. 执行长时间运行的任务:

    • 播放音乐。
    • 下载或上传文件。
    • 同步数据。
    • 定时任务(如通知提醒)。
  2. 无需用户界面的操作:

    • 服务可以在没有窗口的情况下运行,适合处理不需要与用户交互的任务。
  3. 保持应用的核心功能运行:

    • 比如即时通讯应用中的消息推送、位置跟踪、天气情况监听等。

使用后台服务

详见安装包内自带的安卓例程:后台服务例程

1.创建服务

在IDE工程窗口中选中程序集节点;新建文件;选择文件类型为:后台服务,输入服务名称:Ser1 点击确定。

' ****************************************************************************
' 版权说明:Copyright(C) All Rights Reserved VcnStudio
' 程序版本:V1.0
' 服务描述:本服务演示了一个实时在后台获取当前时间并传递给主窗口标签中显示的功能。
' 修改日志:
' ****************************************************************************

' 定义当前服务的类成员变量
变量 类成员1 为 文本型

' 接收子线程传出的消息
变量 类_消息句柄1 为 消息句柄

' 当服务被创建时触发该事件
事件 服务创建完毕()
    调试输出("服务创建完毕")
结束 事件

' 当从外部启动当前服务时、将触发该事件;并返回启动时传入的意图对象
事件 收到指令(源意图 为 意图,标志值 为 整数型,服务ID 为 整数型)
    调试输出("收到服务指令")
    如果(类_消息句柄1 == 空)
        类_消息句柄1 = 创建 消息句柄()
        类_消息句柄1.置收到消息回调(&类_消息句柄1_收到消息)
    结束 如果
    ' 实时获取时间、并显示到主窗口标签中显示
    异步执行首
        ' 在子线程中无限循环获取时间
        判断循环(真)
            变量 当前时间 = 取现行时间到文本("yyyy-MM-dd HH:mm:ss")
            ' 由于安卓系统设计、这里在子线程中获取的时间数据必须先发送给消息句柄
            类_消息句柄1.发送消息(1,当前时间)
            ' 每隔1秒获取一次时间、注意:这里必须添加延时防止CPU占用100%
            延时(1000)
        结束循环
    异步执行尾
结束 事件

函数 类_消息句柄1_收到消息(源对象 为 消息句柄,消息ID 为 整数型,数据值 为 对象)
    ' 收到来自子线程中获取的时间、然后将时间投递给主窗口
    发送事件消息(1,数据值)
结束 函数

' 当服务被系统销毁或内存不足导致服务被关闭时触发该事件
事件 服务被销毁()

结束 事件

2.启动服务并接收后台服务传出的消息及数据值

事件 窗口创建完毕()
    标签1.标题 = "APP启动完毕;窗口创建完毕!"
    接收事件消息(&接收服务数据)
结束 事件

函数 接收服务数据(ID 为 整数型,数据值 为 对象)
    如果(ID == 1)
        ' 获取的时间
        标签1.标题 = 到文本(数据值)
    结束 如果
结束 函数

事件 按钮1.被单击(来源对象 为 视图)
    启动服务("Ser1")
结束 事件

广播

在安卓开发中,广播(Broadcast) 是一种用于在应用程序之间或应用程序内部传递消息的机制。它允许一个组件向系统或其他应用发送事件通知,其他组件可以通过注册接收器来监听这些事件并作出响应。

广播的作用及应用场景

  1. 系统事件通知:

    • 监听系统级别的事件,例如电池电量低、网络状态变化、屏幕亮灭等。
  2. 应用内通信:

    • 在应用的不同组件(如窗口、后台服务)之间传递数据或通知。
  3. 跨应用通信:

    • 不同应用之间可以通过广播共享信息或触发操作。
  4. 全局事件管理:

    • 广播可以用于实现全局事件监听和分发,例如通知用户完成某项任务。

使用广播

1.发送广播

通过意图对象封装待发送的广播消息,然后再使用内置函数 发送全局广播

事件 按钮1.被单击(来源对象 为 视图)
    变量 局_意图 = 创建 意图()
    ' 这里的动作可以自定义,其作用是:定义一个广播标识,在接收广播消息时通过这个动作判断广播来源
    局_意图.动作 = "mymsg"
    局_意图.添加数据("msg","这是在窗口2发送的广播消息")
    发送全局广播(局_意图)
结束 事件

2.接收广播消息

接收广播消息需要先创建一个广播对象,然后通过 收到新广播 事件处理广播消息,代码示例:

' 定义接收广播消息的对象
变量 广播1 为 广播

事件 窗口创建完毕()
    广播1 = 创建 广播()
结束 事件

事件 按钮1.被单击(来源对象 为 视图)
    ' 创建广播之后、必须先注册待监听的动作
    ' 可一次注册多个动作、也可以注册单个动作
    变量 动作 = { "android.intent.action.BATTERY_CHANGED" , "ACTION_VCN_BROADCAST_TESTMSG" }
    广播1.注册监听动作(动作)
    弹出提示("注册广播成功")
结束 事件

事件 广播1.收到新广播(源对象 为 广播,意图对象 为 意图)
    ' 这里返回的意图对象即为发送广播时返回的意图对象
    ' 除了可以接收自定义广播对象外、还可以接收系统广播、例如:手机电池电量被改变
    变量 action 为 文本型 = 意图对象.动作
    如果(action == "android.intent.action.BATTERY_CHANGED")
        ' 这里返回的动作即为电池电量被改变的广播
        ' 通过指定字段名称从意图对象中取出电池电量
        变量 当前电量 为 整数型
        变量 总电量 为 整数型
        变量 电量百分比 为 文本型
        当前电量 = 意图对象.取整数值("level")
        总电量 = 意图对象.取整数值("scale")
        电量百分比 = 到文本(当前电量 / (单精度小数)总电量) + "%"
        标签1.标题 = "电池电量:" + 当前电量 + "," + 电量百分比
    否则 如果(action == "mymsg")
        ' 接收我们从其它窗口、或模块、或后台服务中传递的自定义广播信息
        变量 消息值 为 文本型 = 意图对象.取文本值("msg")
        标签1.标题 = "自定义广播消息:" + 消息值
    结束 如果
结束 事件

事件 按钮2.被单击(来源对象 为 视图)
    广播1.注销广播()
结束 事件

常见系统广播

以下是一些常见的系统广播及用途:

广播名称常量值描述
电池电量低"android.intent.action.BATTERY_LOW"电池电量低
电池电量恢复正常"android.intent.action.BATTERY_OKAY"电池电量恢复正常
系统启动完成"android.intent.action.BOOT_COMPLETED"系统启动完成
屏幕点亮"android.intent.action.SCREEN_ON"屏幕点亮
屏幕熄灭"android.intent.action.SCREEN_OFF"屏幕熄灭
网络状态变化"android.net.conn.CONNECTIVITY_CHANGE"网络状态变化

注意事项

  1. 性能优化:

    • 实际开发时应在 收到新广播 事件中快速完成任务,避免阻塞主线程。如果需要执行耗时操作,可以将任务交给子线程或后台服务。
  2. 注销广播:

    • 广播不使用了,或者完成了任务后,应在适当时候注销广播,以避免内存泄漏。