Android中Binder在项目中的具体使用详解

news/2025/2/22 8:54:27/

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。
👉点击跳转到教程

前言:Binder的介绍
在 Android 中,Binder 是一种跨进程通信(IPC)机制,它是基于进程间通信(IPC)机制中的共享内存和消息传递机制实现的。Binder 的主要作用是在 Android 操作系统中跨进程传递数据和服务,例如 Activity、Service、Broadcast 等都是通过 Binder 实现跨进程通信和交互的

Binder 是 Android 系统的一个重要组成部分,它主要由以下三部分组成:

Binder 驱动:位于底层的驱动程序,它负责提供进程间通信的基础设施和实现对 Binder 对象的创建和跟踪。

Binder API:位于 Java 层,是 Android 应用程序和 Binder 驱动之间的接口,它提供了创建 Binder 服务和跨进程访问 Binder 服务的方法和实现。

Binder 对象:也称为 Binder 服务,是 Android 应用程序中提供跨进程通信的关键对象。每个 Binder 对象都有一个唯一的标识符,被用来标识不同的 Binder 服务,其他进程可以通过这个标识符获取对这个服务的引用并使用它。

在 Android 应用程序中使用 Binder 通常可以通过两种方式实现,一种是使用 AIDL(Android 接口定义语言)定义接口,并通过 Binder 服务实现接口的跨进程调用,另一种是通过 Messenger 实现基于消息的跨进程通信。

本篇使用Binder实现一个模拟第三方QQ登录的一个效果,效果图如下
在这里插入图片描述
一、首先创建服务端程序BinderB,详细步骤如下

1、创建BLoginActivity类和activity_b_login.xml,布局不再给出,java代码如下:

private const val NAME = "android"
private const val PWD = "123456"class BLoginActivity : AppCompatActivity() {private var isStartRemote = falseprivate lateinit var iLogin: ILoginInterfaceprivate var conn = object : ServiceConnection {override fun onServiceConnected(name: ComponentName?, service: IBinder?) {iLogin = ILoginInterface.Stub.asInterface(service)}override fun onServiceDisconnected(name: ComponentName?) {TODO("Not yet implemented")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_b_login)btn_login.setOnClickListener {var account = et_account.text.toString()var pwd = et_password.text.toString()if (TextUtils.isEmpty(account) || TextUtils.isEmpty(pwd)) {ToastUtils.showShort("账号或者密码为空!")return@setOnClickListener}val progress = ProgressDialog(this)progress.setTitle("登录")progress.setMessage("登录中")progress.show()Thread {SystemClock.sleep(2000)runOnUiThread {var loginStatus = falseif (NAME == account && PWD == pwd) {ToastUtils.showShort("登录成功!")loginStatus = truefinish()} else {ToastUtils.showShort("登录失败!")}iLogin.loginCallback(loginStatus, account)progress.dismiss()}}.start()}initBindService()}private fun initBindService() {val intent = Intent()intent.action = "BinderA_Action"intent.`package` = "com.king.learn" //客户端程序的包名bindService(intent, conn, Context.BIND_AUTO_CREATE) isStartRemote = true}override fun onDestroy() {super.onDestroy()if (isStartRemote) {unbindService(conn)}}
}

2、创建服务

class LoginService : Service() {override fun onBind(intent: Intent?): IBinder? {return object : ILoginInterface.Stub() {override fun login() {LogUtils.d("BinderB_LoginService")//单向通信,真实项目中,跨进程都是双向通信,双向服务绑定的//做qq登录,qq分享的时候,需要填入自己的包名,就是这个原因serviceStartActivity()}override fun loginCallback(loginStatus: Boolean, loginUser: String?) {TODO("Not yet implemented")}}}/*** 启动页面*/private fun serviceStartActivity() {val intent = Intent(this, BLoginActivity::class.java)intent.flags = Intent.FLAG_ACTIVITY_NEW_TASKstartActivity(intent)}
}

2.1、并在清单文件中注册服务

 <!--android:enabled="true" 是否可以被系统实例化android:exported="true" 是否可以能被其他应用隐式调用android:process=":remote_server" 表示:应用程序当中需要使用该服务的话,会自动创建名为:remote_server的进程--><serviceandroid:name=".service.LoginService"android:enabled="true"android:exported="true"android:process=":remote_server"><intent-filter><action android:name="BinderB_Action" /></intent-filter></service>

3、创建AIDL名字为ILoginInterface代码如下,服务端程序和客户端程序在同一个包名下面,我这里统一在package com.aidl;

interface ILoginInterface {void login();//登录void loginCallback(boolean loginStatus,String loginUser);//登录回调
}

二、客户端程序A

1、创建步骤类似,首先创建AActivity 和activity_a.xml

class AActivity : AppCompatActivity() {private var isStartRemote: Boolean = falseprivate  var iLogin: ILoginInterface?=null/*** 服务的连接*/private var conn: ServiceConnection = object : ServiceConnection {override fun onServiceConnected(name: ComponentName?, service: IBinder?) {//使用服务端的功能(方法)iLogin = ILoginInterface.Stub.asInterface(service)}override fun onServiceDisconnected(name: ComponentName?) {LogUtils.d("测试")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_a)initBindService()btn_login.setOnClickListener {if (iLogin != null) {try {iLogin?.login()} catch (e: Exception) {e.printStackTrace()}} else {ToastUtils.showShort("请先安装QQ应用!")}}}/*** 绑定服务*/private fun initBindService() {val intent = Intent()//设置Server应用Action(服务的唯一标识)intent.action = "BinderB_Action"//设置Server应用包名intent.`package` = "com.king.kotlinproject"bindService(intent, conn, BIND_AUTO_CREATE)isStartRemote = true}override fun onDestroy() {super.onDestroy()if (isStartRemote) {//解绑服务,一定要记得,不然服务连接异常unbindService(conn)}}
}

2、创建三方应用登录后,返回的服务

class ResultService : Service() {override fun onBind(intent: Intent?): IBinder? {return object : ILoginInterface.Stub() {override fun login() {TODO("Not yet implemented")}override fun loginCallback(loginStatus: Boolean, loginUser: String?) {//第三方登录成功后,不用挂起,直接打印了日志LogUtils.d("loginStatus:$loginStatus/ loginUser:$loginUser")}}}
}

在AndroidManifest.xml清单文件中,进行注册

 <service android:name=".service.ResultService"android:enabled="true"android:exported="true"android:process=":remote"><intent-filter><action android:name="BinderA_Action"/></intent-filter></service>

3、创建对应的AIDL ,ILoginInterface

interface ILoginInterface {void login();//登录void loginCallback(boolean loginStatus,String loginUser);//登录回调
}

日志输入如下:
在服务端B已经启动的情况下,启动客户端程序A,点击进行三方登录
服务端B程序进行日志打印:
在这里插入图片描述
在服务端B程序进行登录后,跳转到客户端程序A,打印的
日志如下:
在这里插入图片描述


http://www.ppmy.cn/news/107832.html

相关文章

为kong网关添加限流插件

限流用于控制发送到上游服务的请求速率。 它可用于防止 DoS 攻击、限制网络抓取和其他形式的过度使用。 如果没有速率限制&#xff0c;客户可以无限制地访问您的上游服务&#xff0c;这可能会对可用性产生负面影响。 一、全局范围内的限流 1、启用限流 [rootmin ~]# curl -i…

【PXIE301-204】基于PXIE 总线的4 路Cameralink Base 图像采集卡

产品概述&#xff1a; PXIE301‐204 一款基于3U PXI Express 总线的高性能4 路CameraLink Base 图像采集卡&#xff0c;该板卡采用Xilinx 的高性能Kintex‐7 系列FPGA 作为主控制器&#xff0c;实现PCI Express 总线接口的转换&#xff0c;图像数据的缓存&#xff0c;以及Camer…

值得收藏的JavaScript 语句

1. 两个日期间的天数 const diffDays (startDate, endDate) >Math.ceil(Math.abs(new Date(startDate) - new Date(endDate)) /(1000 * 60 * 60 * 24));console.log(diffDays("2021-06-01", "2021-06-23")); // 222. 首字母大写 const capitalize (…

Revit楼板问题:楼板连接处以及楼板开洞,一键开洞

在我们做楼梯时&#xff0c;楼梯与楼板处的连接处理不是那么符合实际&#xff0c;会出现一些问题&#xff0c;如下图&#xff0c;这样的连接会导致楼梯配筋时钢筋外露。 我们来学习如何调节楼板与楼板连接处的高度&#xff0c;选中楼梯&#xff0c;点击“编辑楼梯”在所需要更改…

Log4j2 - JNDI 注入漏洞复现(CVE-2021-44228)

文章目录 Apache Log4j简介漏洞介绍影响版本漏洞编号影响组件应用 环境准备靶场搭建漏洞利用利用工具使用方式 反弹shell操作 漏洞修复建议 Apache Log4j简介 Apache log4j 是 Apache 的一个开源项目&#xff0c; Apache log4j2 是一个 Java 的日志记录工具。该工具重写了 log4…

Deep Frequency Filtering for Domain Generalization论文阅读笔记

这是CVPR2023的一篇论文&#xff0c;讲的是在频域做domain generalization&#xff0c;找到频域中generalizable的分量enhance它&#xff0c;suppress那些影响generalization的分量 DG是一个研究模型泛化性的领域&#xff0c;尝试通过各自方法使得模型在未见过的测试集上有良好…

OpenAI竞对再被谷歌加注!4.5亿美元新融资到位,累计已吸金14.5亿美元

量子位 | 公众号 QbitAI OpenAI之外&#xff0c;第二不差钱的AI初创公司出现了&#xff01; 研发出ChatGPT最强竞品Claude的Anthropic公司&#xff0c;在谷歌投资之后&#xff0c;再次官宣获得了4.5亿美元C轮融资。 这轮收购之后&#xff0c;Anthropic资金一跃达到14.5亿美元…

用户账号注册的风险及安全措施

安全风险&#xff08;包括但不限于&#xff09;&#xff1a; 密码泄露&#xff1a;用户的密码可能被攻击者窃取&#xff0c;从而导致账户被盗。恶意注册&#xff1a;攻击者可能会使用自动化程序进行大量恶意注册&#xff0c;占用系统资源。密码猜测&#xff1a;攻击者可能会尝…