当前位置: 首页 > news >正文

学习Android的第二十九天

目录

Android Service 与 Activity 通讯

范例

Android Service Alarm 定时广播

Alarm

Alarm 使用流程

范例

Android IBinder

Binder

为什么是 Binder ?


Android Service 与 Activity 通讯

Activity 与 Service 通信的媒介就是 Service 中的 onBind() 方法,onBind() 方法会返回一个自定义的 Binder 对象。

  1. 在自定义的 Service 类中,我们会创建一个继承自 Binder 的自定义 Binder 类,其中包含了我们想要暴露给 Activity 的方法。这个 Binder 类负责实现跨进程通信所需的接口。
  2. 在 Service 类中,我们需要实例化这个自定义的 Binder 类,并且在 onBind() 方法中返回这个 Binder 对象。
  3. 在 Activity 类中,我们需要实例化一个 ServiceConnection 对象,并且重写 onServiceConnected() 方法。当连接到 Service 时,系统会调用 onServiceConnected() 方法,并提供一个 Binder 对象,通过它可以调用 Service 中暴露的方法。

范例

package com.example.myapplication2;import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;public class MyService extends Service {public void doSomething() {}// 自定义的 Binder 类public class MyBinder extends Binder {MyService getService() {return MyService.this;}// 暴露给 Activity 的方法public void doSomething() {// 在这里执行具体的操作}}private final IBinder mBinder = new MyBinder();@Overridepublic IBinder onBind(Intent intent) {return mBinder;}
}
package com.example.myapplication2;import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private MyService mService;private boolean mBound = false;// ServiceConnection 对象private ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName className, IBinder service) {MyService.MyBinder binder = (MyService.MyBinder) service;mService = binder.getService();mBound = true;// 在这里可以调用 Service 中暴露的方法mService.doSomething();}@Overridepublic void onServiceDisconnected(ComponentName arg0) {mBound = false;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 启动 ServiceIntent intent = new Intent(this, MyService.class);startService(intent);}@Overrideprotected void onStart() {super.onStart();// 绑定到 ServiceIntent intent = new Intent(this, MyService.class);bindService(intent, mConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onStop() {super.onStop();// 解绑 Serviceif (mBound) {unbindService(mConnection);mBound = false;}}
}

Android Service Alarm 定时广播

对于在 Android 应用中执行定时任务,特别是需要长期在后台运行的定时任务,使用 Alarm 机制是更为可靠和适合的选择。相比之下,Timer 类存在一些局限性,如在设备休眠时无法保证准确执行定时任务。

Alarm 机制通过设置系统级别的闹钟来触发某个操作,即使应用处于后台或设备休眠状态,也能够唤醒 CPU 并执行相应的任务。这种方式适合于需要长期在后台持续执行的定时任务,比如轮询服务器进行数据更新或状态确认等。

同时,在使用 Alarm 机制时,需要注意区分 CPU 唤醒与屏幕唤醒。CPU 唤醒是指在设备休眠状态下唤醒 CPU 执行任务,而屏幕唤醒则是指设备从休眠状态恢复到亮屏状态。通常情况下,我们希望定时任务能够唤醒 CPU 执行而不会唤醒屏幕,以节省设备电量并保持用户体验。

总的来说,针对需要长期在后台执行的定时任务,推荐使用 Alarm 机制,它可以可靠地唤醒 CPU 执行任务,且能够有效管理定时任务的触发和执行。

Alarm

对于 Android 中 AlarmManager 的 set() 方法,参数包括类型(type)、开始时间(startTime)和 PendingIntent 对象(pi),这些参数决定了闹钟的执行方式和动作。

1. 类型(type):

  1. AlarmManager.ELAPSED_REALTIME:相对于系统启动时间的相对时间,手机睡眠时不可用。
  2. AlarmManager.ELAPSED_REALTIME_WAKEUP:相对于系统启动时间的相对时间,手机睡眠时会唤醒系统。
  3. AlarmManager.RTC_WAKEUP:绝对时间,手机睡眠时会唤醒系统。
  4. AlarmManager.POWER_OFF_WAKEUP:在手机关机状态下也能正常提示功能,但受SDK版本影响,可能并不是所有版本都支持。

   
2. 开始时间(startTime):

  • 决定了闹钟的第一次执行时间,以毫秒为单位。可以使用 SystemClock.elapsedRealtime() 或 System.currentTimeMillis() 根据类型来获取合适的时间。 

3. PendingIntent 对象(pi):

用于绑定闹钟的执行动作,比如发送广播、给出提示等等。

  • 如果通过启动服务来实现闹钟提示,应该使用 `Pending.getService()` 方法获取 PendingIntent 对象。
  • 如果通过广播来实现闹钟提示,应该使用 `PendingIntent.getBroadcast()` 方法获取 PendingIntent 对象。
  • 如果通过 Activity 来实现闹钟提示,应该使用 `PendingIntent.getActivity()` 方法获取 PendingIntent 对象。

正确选择 PendingIntent 获取方法很重要,否则虽然不会报错,但可能无法看到闹钟提示效果。根据实际情况选择合适的 PendingIntent 获取方法,确保闹钟的执行动作能够按预期进行。

Alarm 使用流程

使用 Alarm 的一般流程如下:

1、获取 AlarmManager 对象:

AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);

2、使用 set() 方法设置定时任务:

int durtime = 2 * 1000; // 单位毫秒
long triggerAtTime = SystemClock.elapsedRealtime() + durtime;
manager.set(AlarmManager.RTC_WAKEUP, triggerAtTime, pendingIntent);

3、定义一个 Service,在其 onStartCommand() 方法中开辟一条事务线程,用于处理定时逻辑。

4、定义一个广播(Broadcast),用于启动 Service。

5、在 AndroidManifest.xml 文件中注册 Service 和 Broadcast。

请注意,对于 Android 4.4+(API 19)的设备,Alarm 任务的触发时间可能会变得不准确,有可能会有延时。这是系统为了进行耗电性的优化所做的调整。如果需要准确无误的触发时间,可以考虑使用 setExact() 方法。

范例

1、创建一个新的 Java 类,命名为 AlarmReceiver,继承自 BroadcastReceiver:

package com.example.myapplication2;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;public class AlarmReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "定时任务触发", Toast.LENGTH_SHORT).show();}
}

2、在 AndroidManifest.xml 文件中注册 AlarmReceiver 广播:

<receiver android:name=".AlarmReceiver" />

3、修改MainActivity.java:

package com.example.myapplication2;import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);Intent intent = new Intent(this, AlarmReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);long triggerAtTime = SystemClock.elapsedRealtime() + 5000; // 5秒后触发alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);}
}

Android IBinder

IBinder是Android系统中用于远程对象通信的关键接口之一。以下是您提供的内容的总结:

IBinder的作用:

  • IBinder是远程对象的基本接口,用于高性能的轻量级远程调用机制。

IBinder的使用:

  • 不仅用于远程调用,也可用于进程内调用。
  • 一般情况下,我们通过继承Binder类来实现IBinder接口,而不是直接实现该接口。

主要方法:

  • transact():向远程IBinder对象发送调用。
  • onTransact():响应接收到的调用。
  • 这些方法是同步执行的,比如transact()在对方的onTransact()方法调用完成之前不会返回。

数据传输:

  • transact()发送的数据是通过Parcel进行传输的。
  • Parcel是一种通用的缓冲区,除了数据外,还包含描述其内容的元数据。
  • 元数据用于管理IBinder对象的引用,以便在进程间移动Parcel时保存这些引用。

进程间通信:

1、IBinder和Binder之间的管理类似于唯一标识符。
2、在操作远程对象时,可能需要确保它们是有效的。可以使用以下方法:

  • 当目标进程不存在时,使用transact()方法会抛出RemoteException异常。
  • 调用pingBinder()时,如果目标进程不存在,则返回false。
  • 可以使用linkToDeath()方法向IBinder注册一个IBinder.DeathRecipient,在代表的进程退出时调用。

Binder

在 Binder 机制中,通常存在以下组件和调用流程:

Client(客户端):

  • 客户端是使用 Binder 机制进行远程调用的应用程序或组件。
  • 客户端通过获取服务的代理对象(Proxy)来调用远程服务的方法。
  • 客户端通过 Binder 机制将请求发送到服务端。

Server(服务端):

  • 服务端是提供远程服务的应用程序或组件。
  • 服务端通过实现具体的业务逻辑来响应客户端的请求。
  • 服务端通过 Binder 机制接收来自客户端的请求,并执行相应的操作。

Service Manager(服务管理器):

  • 服务管理器是 Android 系统中的一个系统服务,负责维护 Binder 对象的注册表。
  • 它允许客户端通过 Binder 对象的名称来查找远程服务,并获取其代理对象。

Binder 驱动程序:

  • Binder 驱动程序是 Android 系统中的内核模块,负责处理 Binder 通信的底层细节。
  • 它负责跟踪 Binder 对象的生命周期、实现进程间通信和线程间通信的机制。

Binder 机制的调用流程如下:

  1. 客户端通过 Service Manager 获取远程服务的代理对象(Proxy)。
  2. 客户端调用代理对象的方法,传递参数和回调接口(如果需要)。
  3. 代理对象将调用请求封装成 Binder 消息,并通过 Binder 驱动程序发送给服务端。
  4. 服务端接收到 Binder 消息后,解析消息内容,并执行相应的操作。
  5. 服务端执行完操作后,将结果返回给客户端,同样通过 Binder 消息传递。
  6. 客户端接收到结果后,执行相应的逻辑处理。

为什么是 Binder ?

Binder 机制之所以成为 Android 进程间通信的基础,带来了很多便利和好处,

主要归功于以下几个原因:

  • 高效的进程间通信机制:Binder 机制在底层实现了高效的进程间通信机制,包括线程间通信和进程间通信。这使得在 Android 系统中,不同应用程序或者同一个应用程序的不同进程之间能够进行快速、可靠的通信。
  • 抽象了底层细节:使用 Binder 机制时,开发者不需要关心底层通信的实现细节,如进程间通信的具体实现、数据传输方式等。通过 AIDL(Android Interface Definition Language)定义接口后,Binder 机制会自动处理数据的传输和远程方法的调用,使得开发者只需专注于业务逻辑的实现。
  • 提供了灵活的接口定义方式:通过 AIDL 定义接口,开发者可以自由地描述远程服务的接口,包括方法的签名、参数以及返回值。这种灵活的接口定义方式使得不同进程之间的通信更加灵活和方便。
  • 内置了安全机制:Binder 机制内置了安全机制,确保了进程间通信的安全性。例如,Binder 会对传输的数据进行序列化和反序列化,同时通过权限验证等方式确保通信的安全性,防止恶意程序对进程间通信进行攻击。
  • 统一的通信接口:在 Android 系统中,大部分的跨进程通信都是通过 Binder 机制进行的。这种统一的通信接口使得不同应用程序之间的通信更加一致,提高了系统的稳定性和可维护性。

综上所述,Binder 机制作为 Android 系统中进程间通信的基础,通过其高效、抽象、安全、灵活的特性,极大地简化了开发者进行进程间通信的复杂度,提高了系统的性能和稳定性。

相关文章:

学习Android的第二十九天

目录 Android Service 与 Activity 通讯 范例 Android Service Alarm 定时广播 Alarm Alarm 使用流程 范例 Android IBinder Binder 为什么是 Binder ? Android Service 与 Activity 通讯 Activity 与 Service 通信的媒介就是 Service 中的 onBind() 方法&#xff0…...

SpringMVC重点记录

目录 1.学习重点2.回顾MVC3.回顾servlet4.初始SpringMVC4.1.为什么要学SpringMVC?4.2.SpringMVC的中重点DispatcherServlet4.3.SpringMVC项目的搭建4.4.MVC框架要做哪些事情?4.5.可能会遇到的问题 5.SpringMVC的执行原理6.使用注解开发SpringMVC7.Controller控制总结8.RestF…...

一条 SQL 更新语句如何执行的

Server 层 存储引擎层 总流程 查询语句 连接器 查询缓存 分析器 优化器 执行器 更新语句 redo log&#xff08;节省的是随机写磁盘的 IO 消耗&#xff08;转成顺序写&#x…...

Github上哪些好用的安全工具1

专注于web漏洞挖掘、内网渗透、免杀和代码审计&#xff0c;感谢各位师傅的关注&#xff01;网安之路漫长&#xff0c;与君共勉&#xff01; URLFinder 一款快速提取网页信息的工具。该项目可以快速爬取网页上的 URL 地址、JS 文件里的 API 接口等信息&#xff0c;支持批量抓取…...

手写Mybatis自动填充插件

目录 一、Mybatis插件简介&#x1f959;二、工程创建及前期准备工作&#x1f96b;实现代码配置文件 三、插件核心代码实现&#x1f357;四、测试&#x1f953; 一、Mybatis插件简介&#x1f959; Mybatis插件运行原理及自定义插件_简述mybatis的插件运行原理,以及如何编写一个…...

upload文件上传漏洞复现

什么是文件上传漏洞&#xff1a; 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷&#xff0c;而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马&#xff0c;病毒&#xff0c;恶意脚本或者WebShell等。“…...

Docker 安装部署 SqlServer 数据库

Docker 安装部署 SqlServer 数据库 背景&#xff1a; ​ 最近在开发数据中台数据集成模块&#xff0c;需要对接大量的数据做测试&#xff0c; 由于SqlServer 下载安装会耗费大量时间&#xff0c;所以采用 Docker 安装 Sqlserver 的方式部署数据库。 1、拉去 sqlserver 镜像 …...

cmath 中cos sin等常用函数的坑(弧度角度换算)

cmath中三角函数的输入是弧度,不是角度.忘了这件事,找bug找了好久! 弧度是旧称弪。在数学和物理中&#xff0c;弧度是角的度量单位。它是由国际单位制导出的单位&#xff0c;单位缩写是rad。弧度是指在一个圆中&#xff0c;弧长和半径之比&#xff0c;即|弧度|弧长半径。 角度…...

深度解析HTTP反向代理-okey proxy

反向代理這個概念可能並不常見&#xff0c;但其實它對於提升網路安全和訪問速度方面發揮著很大作用。 HTTP反向代理&#xff08;HTTP Reverse Proxy&#xff09;是一種特殊的代理伺服器&#xff0c;首先它能夠接收互聯網上的連接請求&#xff0c;然後將這些請求轉發給內部網路…...

SwinIR训练报错解决

swinir训练报错解决 记录swinir图像超分重建算法复现过程中的报错信息,并提供相应的解决方案 报错信息 UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at C:\actions-runner\_work\pyto…...

C++类和对象一

#include <iostream> using namespace std;//设计一个学生类 class CStudent {public: //公有成员void InputData(){cout << "请输入学号";cin >> sno;cout << "请输入姓名";cin >> sname;cout << "请输入分…...

Linux之线程互斥

目录 一、问题引入 二、线程互斥 1、相关概念 2、加锁保护 1、静态分配 2、动态分配 3、锁的原理 4、死锁 三、可重入与线程安全 1、概念 2、常见的线程不安全的情况 3、常见的线程安全的情况 4、常见不可重入的情况 5、常见可重入的情况 6、可重入与线程安全联系…...

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…...

二刷代码随想录算法训练营第二十三天 | 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

目录 一、669. 修剪二叉搜索树 二、108. 将有序数组转换为二叉搜索树 三、538. 把二叉搜索树转换为累加树 一、669. 修剪二叉搜索树 题目链接&#xff1a;力扣 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a; 你修剪的方式不对&#xff0c;我来给你纠正一下&#…...

信息抽取在旅游行业的应用:以景点信息抽取为例

开源项目推荐 今天先给大家推荐一个开源项目&#xff0c;多模态AI能力引擎平台: 免费的自然语言处理、情感分析、实体识别、图像识别与分类、OCR识别、语音识别接口&#xff0c;功能强大&#xff0c;欢迎体验。 https://gitee.com/stonedtx/free-nlp-api 场景描述 在旅游行业…...

Linux——基础指令

一、Linux目录结构 1、树形结构 Linux只有一个根目录 / &#xff0c;所有文件都在它下面 2、Linux路径的描述方式 在Linux系统中&#xff0c;路径之间的层级关系&#xff0c;使用&#xff1a; / 来表示 eg&#xff1a; /usr/local/hello.txt 注意&#xff1a; 开头/表示根…...

H5 带网站测速引导页源码

源码名称&#xff1a;带网站测速引导页源码 源码介绍&#xff1a;一款带网站测速功能的引导页源码 需求环境&#xff1a;H5 下载地址&#xff1a; https://www.changyouzuhao.cn/10717.html...

案例分析篇07:数据库设计相关28个考点(23~28)(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…...

Word中解决插入脚注导致的分页位置错误问题

先放一个截图&#xff1a; 上面的截图中&#xff0c;样式为标题3的段落“四、固执的念头”前插入了连续型分节符&#xff0c;并且该分节符的样式为正文&#xff0c;前后的正文段落中有脚注&#xff0c;结果在分页时&#xff0c;标题3段落“四、固执的念头”后的正文段落自动进入…...

2024/03/14(网络编程·day2)

一、思维导图 二、TCP通信 //服务器 #include<myhead.h>#define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.117.103" //服务器IP int main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,…...

GPU算力高效利用:Pixel Language Portal在单卡多实例部署中的资源隔离与负载均衡教程

GPU算力高效利用&#xff1a;Pixel Language Portal在单卡多实例部署中的资源隔离与负载均衡教程 1. 引言&#xff1a;为什么需要单卡多实例部署 在AI应用开发中&#xff0c;GPU资源往往是稀缺且昂贵的。Pixel Language Portal作为一款基于Tencent Hunyuan-MT-7B的高端翻译工…...

基于Phi-4-mini-reasoning的智能运维异常检测系统

基于Phi-4-mini-reasoning的智能运维异常检测系统 1. 运维监控的痛点与智能化需求 运维团队每天都要面对海量的日志数据、监控指标和系统告警。传统监控系统往往只能做到简单的阈值告警&#xff0c;当系统出现异常时&#xff0c;运维人员需要手动翻阅成千上万条日志&#xff…...

别只盯着时钟了!用Vivado的Set_Data_Check搞定FPGA里两个数据信号的时序检查(附工程源码)

FPGA时序约束进阶&#xff1a;用Set_Data_Check精准控制数据信号时序关系 在FPGA设计中&#xff0c;时序约束是确保电路功能正确性的关键环节。大多数工程师对时钟与数据信号之间的setup/hold约束已经驾轻就熟&#xff0c;但当面对两个数据信号之间的时序关系时&#xff0c;却常…...

KityMinder云存储与分享功能完整指南:打造高效团队协作体验

KityMinder云存储与分享功能完整指南&#xff1a;打造高效团队协作体验 【免费下载链接】kityminder 百度脑图 项目地址: https://gitcode.com/gh_mirrors/ki/kityminder KityMinder作为百度FEX团队开发的在线思维导图工具&#xff0c;其强大的云存储与分享功能让团队协…...

告别手动重复!用Python+ArcPy实现多要素批量裁剪年度影像的保姆级教程

PythonArcPy自动化遥感影像裁剪&#xff1a;从原理到实战的完整解决方案 遥感影像处理是GIS工程师的日常必修课。每当拿到新一年的土地利用数据或行政区划影像时&#xff0c;最头疼的莫过于要为每个行政单元单独裁剪每年的数据。我曾花费整整一周时间手动处理30个乡镇5年的NDVI…...

南北阁模型新玩法:一键部署极简WebUI,体验手机短信般AI对话

南北阁模型新玩法&#xff1a;一键部署极简WebUI&#xff0c;体验手机短信般AI对话 还在用那些界面老旧、反应迟钝的AI对话工具吗&#xff1f;每次发送问题后&#xff0c;只能盯着屏幕上的加载图标干等&#xff0c;几秒甚至十几秒后才能看到一大段文字“啪”地一下弹出来&…...

别让电源拖后腿!手把手教你搞定Xilinx 7系列FPGA(以XC7K325T为例)的供电设计

别让电源拖后腿&#xff01;手把手教你搞定Xilinx 7系列FPGA&#xff08;以XC7K325T为例&#xff09;的供电设计 第一次翻开Xilinx 7系列FPGA的硬件手册时&#xff0c;相信不少工程师都会被密密麻麻的电源轨搞得头晕目眩。VCCINT、VCCBRAM、VCCO、VMGTAVCC...这些看似简单的电压…...

苹果设备激活锁终极解锁指南:5步免费绕开iOS 15-16的iCloud限制

苹果设备激活锁终极解锁指南&#xff1a;5步免费绕开iOS 15-16的iCloud限制 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 还在为忘记Apple ID密码而无法使用自己的iPhone或iPad而烦恼吗&#xff1f;…...

2026硬核对比:Claude 4.6官网双版本解析与Gemini 3.1 Pro镜像如何选

对于追求极致编码质量与深度推理的开发者与技术决策者&#xff0c;2026年Anthropic推出的Claude 4.6系列&#xff08;含旗舰Opus与高性价比Sonnet&#xff09;在智能体&#xff08;Agent&#xff09;能力与长上下文处理上树立了新标杆。 若想在国内网络环境下零成本深度对比其…...

YimMenu完全指南:GTA5免费辅助工具从入门到精通

YimMenu完全指南&#xff1a;GTA5免费辅助工具从入门到精通 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …...