Android bindservice绑定服务,并同步返回service对象的两个方法

先上一段代码:

private  IDeviceService deviceService = null;
private ServiceConnection conn=null;
private synchronized void bindyourservice() {    Intent intent = new Intent();intent.setPackage("servicepackagename");intent.setAction("serviceactionname");conn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {               deviceService = IDeviceService.Stub.asInterface(iBinder);}@Overridepublic void onServiceDisconnected(ComponentName componentName) {.....................................             }};try {if (bindService(intent, mConn, Service.BIND_AUTO_CREATE)) {...............................} else {....................}} catch (SecurityException e) {.........................}}

这个是最早绑定服务的方式,bindService返回绑定服务状态,访问服务接口需在取到ServiceConnection连接后再访问,整个过程是异步的,而且就算开线程去绑定服务、加锁也没办法在一个方法里面返回这个service对象,原因是这个方法里面的实现:

/frameworks/base/core/java/android/app/ContextImpl.java

看下这个的代码:

  public boolean bindService(Intent service, ServiceConnection conn, int flags) {warnIfCallingFromSystemProcess();return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,getUser());}@Overridepublic boolean bindService(Intent service, int flags, Executor executor, ServiceConnection conn) {return bindServiceCommon(service, conn, flags, null, null, executor, getUser());}@Overridepublic boolean bindIsolatedService(Intent service, int flags, String instanceName,Executor executor, ServiceConnection conn) {warnIfCallingFromSystemProcess();if (instanceName == null) {throw new NullPointerException("null instanceName");}return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser());}@Overridepublic boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,UserHandle user) {return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, user);}/** @hide */@Overridepublic boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,Handler handler, UserHandle user) {if (handler == null) {throw new IllegalArgumentException("handler must not be null.");}return bindServiceCommon(service, conn, flags, null, handler, null, user);}.....................private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,String instanceName, Handler handler, Executor executor, UserHandle user) {....................
}

 bindServiceCommon是个私有方法,里面又套了几层代码,太长,翻起来就是整个系统bindservice的流程了。

关键点,bindservice执行的时候接收的Handler是 mMainThread.getHandler(),这个是APP的主线程,也就是无论外部怎么折腾,这个是在主线程接收的。

在上面这段系统代码段里面,有两个方法是可以使用的:

//method 1
public boolean bindService(Intent service, int flags, Executor executor, ServiceConnection conn)
//method 2
/** @hide */
@Override
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,Handler handler, UserHandle user)

1、bindService

在bindService有一个传参executor,接收ServiceConnection放到了这个里面:

private boolean[] isBind = {false};
private CountDownLatch latch = new CountDownLatch(1);
private boolean bindyourservice(final Context context){if(deviceService==null){latch = new CountDownLatch(1);Executor executor= Executors.newSingleThreadExecutor();executor.execute(new Runnable() {@Overridepublic void run() {mConn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName className, IBinderiBinder) {deviceService = IDeviceService.Stub.asInterface(iBinder);isBind[0] =true;latch.countDown();}@Overridepublic void onServiceDisconnected(ComponentName className) {                          isBind[0] =false;latch.countDown();}};Intent intent = new Intent();intent.setPackage("yourservicename");intent.setAction("yourserviceaction");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {boolean bind=bindService(intent, Context.BIND_AUTO_CREATE,executor,mConn);if(!bind){                               isBind[0] =false;latch.countDown();}}}});if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {                   try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}                   if(!isBind[0])return false;}else{                   return false;}}         return true;}

需要注意的是Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q,这个方法是android7.0及以后提供的。

2、bindServiceAsUser

也可以实现方法1的功能,只不过把接收对象换成了Handler ,bindServiceAsUser是系统隐藏方法,需通过反射方法使用,至于bindServiceAsUser是否早于android7.0之前就有,无法确认。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go语言之空接口与类型断言

Go 语言中,接口是一种强大的抽象机制。其中,空接口(interface{})和类型断言为我们提供了处理任意类型与类型检查的能力。 一、空接口(interface{}) 空接口是 Go 中最特殊的接口:不包含任何方法…

三、OrcaSlicer预设显示

一、界面类 主框架使用的是wxWidgets库;3D模型的渲染区的控件,使用的是imgui库。 1、Plater 此类在OrcaSlicer\src\slic3r\GUI\Plater.hpp文件中定义 1.1 Plater::priv 此结构体是Plater的数据类,各种数据的对象和指针保存在此结构体中。如…

00 QEMU源码中文注释与架构讲解

QEMU源码中文注释与架构讲解 先占坑:等后续完善后再更新此文章 注释作者将狼才鲸创建日期2025-05-30更新日期NULL CSDN阅读地址:00 QEMU源码中文注释与架构讲解Gitee源码仓库地址:才鲸嵌入式/qemu 一、前言 参考网址 QEMU 源码目录简介qe…

一、Sqoop历史发展及原理

作者:IvanCodes 日期:2025年5月30日 专栏:Sqoop教程 在大数据时代,数据往往分散存储在各种不同类型的系统中。其中,传统的关系型数据库 (RDBMS) 如 MySQL, Oracle, PostgreSQL 等,仍然承载着大量的关键业务…

【Halcon】图像分割中的 regiongrowing 与dyn_threshold 动态阈值 算法详解对比

图像分割中的 regiongrowing 与动态阈值算法详解对比 在使用 HALCON 进行图像处理时,图像分割是最常见也最关键的操作之一。本文将深入讲解 regiongrowing 算子的原理与使用方法,并与另一常见方法——动态阈值 (dyn_threshold) 进行详细对比&#xff0c…

Docker部署项目无法访问,登录超时完整排查攻略

项目背景:迁移前后端应用,prod环境要求保留443端口,开发环境37800端口,后端容器端口为8000,前端为80,fastAPI对外端口为41000 生产环境部署在VM01,开发环境部署在VM03,在VM01配置nginx转发 [r…

充电便捷,新能源汽车移动充电服务如何预约充电

随着新能源汽车的普及,充电便捷性成为影响用户体验的关键因素之一。传统的固定充电桩受限于地理位置和数量,难以完全满足用户需求,而移动充电服务的出现,为车主提供了更加灵活的补能方式。通过手机APP、小程序或在线平台&#xff…

探索C++标准模板库(STL):从容器到底层奥秘-全面解析String类高效技巧(上篇)

前引:在现代软件开发中,字符串处理是几乎所有程序的核心需求之一。无论是文本解析、网络通信,还是用户交互,高效且安全的字符串操作能力直接决定了代码的质量与可维护性。而C标准模板库(Standard Template Library, ST…

Python爬虫实战:抓取百度15天天气预报数据

🌐 编程基础第一期《9-30》–使用python中的第三方模块requests,和三个内置模块(re、json、pprint),实现百度地图的近15天天气信息抓取 记得安装 pip install requests📑 项目介绍 网络爬虫是Python最受欢迎的应用场景之一&…

HTML常见事件详解:从入门到实战应用

前言 在Web开发中,事件是用户与网页交互的核心机制。HTML事件让我们能够响应用户的各种操作,如点击、鼠标移动、键盘输入等。掌握HTML事件是前端开发的基础技能之一,本文将深入探讨HTML中的常见事件类型及其实际应用。 HTML事件概览总结 H…

模具制造业数字化转型:精密模塑,以数字之力铸就制造基石

模具被誉为 “工业之母”,是制造业的重要基石,其精度直接决定了工业产品的质量与性能。在工业制造向高精度、智能化发展的当下,《模具制造业数字化转型:精密模塑,以数字之力铸就制造基石》这一主题,精准点明…

深度解读漏洞扫描:原理、类型与应用实践

在网络安全领域,漏洞就像隐藏在系统中的定时炸弹,随时可能被攻击者利用,导致数据泄露、服务瘫痪等严重后果。而漏洞扫描作为发现这些潜在威胁的 “侦察兵”,是保障网络安全的重要防线。本文将全面介绍漏洞扫描的相关知识&#xff…

[HNCTF 2022 Week1]silly_zip

下载附件 解压发现需要密码 用010打开看看,发现是伪加密 改成00点击保存 解压后得到图片 感觉图片看着怪怪的,修改一下高度看看有没有其他线索 把47改成78 最后得到flag

Facebook 的隐私保护措施是否足够?技术观点

在数字时代,隐私保护成为了公众关注的焦点,尤其是对于拥有数十亿用户的社交媒体巨头 Facebook 来说,其隐私保护措施的有效性更是备受瞩目。本文将从技术角度探讨 Facebook 的隐私保护措施是否足够。 数据收集与使用 Facebook 收集用户数据的…

cocosCreator 1.8 升级到 2.4

现在负责的一个运营中的商业项目,使用的是 cocosCreator1.8,之前没有做好设计,所以东西都是直接加载在内存中的,到了现在性能问题逐渐暴露出来,讨论之后想进行引擎升级,升级到cocosCreator 2.4。 官方的升…

ubuntu 制作 ssl 证书

安装 openssl sudo apt install openssl 生成 SSL 证书 # 生成私钥 (Private Key) openssl genrsa -out private.key 2048 在当前目录生成 private.key # 生成证书签名请求 (CSR - Certificate Signing Request) openssl req -new -key private.key -out certificate.csr -…

【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤

在Java开发的世界里,选择一个强大的集成开发环境(IDE)是迈向高效编程的第一步。而IntelliJ IDEA无疑是Java开发者中最受欢迎的选择之一。它以其强大的功能、智能的代码辅助和简洁的用户界面,帮助无数开发者快速构建和部署Java项目…

WEB3——什么是ABI

怎么获得ABI? 在编译完合约后,可以在左边下面点击复制ABI ABI(Application Binary Interface,应用二进制接口)是用来让前端或服务端 JavaScript 代码与智能合约进行交互的桥梁,它描述了合约的函数、事件和…

移动安全Android——客户端数据安全

本地文件权限配置 测试流程 (1)手机运行待测APP应用,adb执行命令找到APP包名 adb shell dumpsys activity top|findstr ACTIVITY (2)adb shell 进入设备,以Root权限进入/data/data/package包名目录下 c…

拉普拉斯噪声

1. 概念 拉普拉斯噪声是一种连续概率分布生成的随机噪声,其核心特点是符合拉普拉斯分布。这种噪声被特意添加到数据(尤其是查询结果或统计量)中,以实现差分隐私这一严格的隐私保护框架。 核心目的: 在保护数据集中的个…