【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

这篇具有很好参考价值的文章主要介绍了【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Binder介绍

Android 中的 Binder 是一个进程间通信机制,它允许不同进程之间相互调用方法和传递数据。Binder 主要用于实现系统服务和应用程序之间的通信,以及实现 IPC(Inter-Process Communication,进程间通信)。

Binder 的核心是 Binder 驱动程序,它负责管理不同进程之间的通信。每个进程都可以创建自己的 Binder 对象作为服务提供者,也可以获取其他进程提供的 Binder 对象作为客户端使用。这些 Binder 对象都必须通过 Binder 驱动来进行跨进程通信。

机制来说: Binder是一种进程间通信机制
驱动来说: Binder是一个虚拟物理设备驱动
应用层来说:Binder是一个能发起通信的Java类

在 Android 开发中,我们可以通过 AIDL(Android Interface Definition Language)来定义自己的 Binder 接口,并实现相应的服务提供者和客户端。AIDL 生成的代码可用于在不同进程之间进行 IPC 通信。


Binder和其他进程通信方案的比较

Binder与传统IPC对比
Binder 共享内存 Socket
性能 需要拷贝一次 无需拷贝 需要拷贝两次
特点 基于C/S架构,易用性高 控制复杂,易用性差 基于C/S 架构,作为一款通用接口,其传输效率低,开销大
安全性 为每个APP分配UID,同时支持实名和匿名 依赖上层协议访问,接入点是开放的,不安全

Binder 机制组成

Binder(IInterface 接口) 该类定义了远程服务的接口,用于在客户端和服务端之间通信
IBinder 接口 该类是 Binder 的实现类,提供了轻量级的进程间通信能力
ServiceManager 该类提供了一种注册和查找 Binder 服务的机制
Binder驱动程序 该驱动程序是 Binder 进程间通信的核心,用于管理 Binder 连接、数据传输、线程等操作

Binder 机制为 Android 开发提供了一种高效、灵活的进程间通信方式,使得应用程序能够更加方便地进行跨进程数据共享和调用远程服务。


AIDL与 Binder 的关系

AIDL(Android Interface Definition Language,Android 接口定义语言)是 Android 系统中用于实现进程间通信(IPC)的一种机制。AIDL 可以帮助开发者在不同的应用程序之间或不同进程之间实现远程方法调用,从而实现跨进程的数据共享和交互。

Binder 是 Android 系统中用于实现 IPC 的核心驱动程序,它可以为 AIDL 定义的接口提供底层支持。Binder 驱动程序通过管理进程间的连接、数据传输等操作,完成了基于 AIDL 的进程间通信功能。

AIDL 与 Binder 的关系可以理解为:AIDL 提供了描述跨进程间通信接口的语言,而 Binder 则是实现 AIDL 接口调用的内部框架。在 Android 应用程序中,一般都是通过在 AIDL 文件中定义跨进程访问的接口,并通过 Binder 实现这些接口,从而实现应用程序之间的通信。


使用Binder进行进程间通信例子

首先,我们需要创建两个端,分别是服务端客户端

服务端

创建一个项目,名字叫MyBinderService
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
然后创建AIDL文件

注意:aidl文件夹是需要自己创建的,且文件夹在main文件夹下面,和 java文件夹平级

【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

当我们在aidl文件夹创建aidl文件时,遇到这个错误:
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

这个提示意味着需要在 build.gradle 文件中设置 buildFeatures.aidl 为 true 才能使用 AIDL 技术
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

 buildFeatures {
    aidl = true
 }

此时我们看到上面的aidl文件夹也变颜色了。

服务端应用程序中,我们需要先定义一个 AIDL 接口,为客户端提供数据获取的方法。
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
然后我们需要实现接口方法并注册到系统中,这里使用一个 Service 来实现:
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

完整代码

public class MyService extends Service {

    private static final int NOTIFICATION_ID = 1001; // 前台通知 ID

    private final IBinder mBinder = new MyBinder();

    @Override
    public IBinder onBind(Intent intent) {
        Log.e("Binder响应:", "已经绑定到Binder上面了");
        return mBinder;
    }

    static class MyBinder extends IMyService.Stub {
        @Override
        public long getCurrentTimestamp() throws RemoteException {
            long time = System.currentTimeMillis();
            Log.e("Binder数据:", "服务端的时间戳:" + time);
            return time;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager manager = getSystemService(NotificationManager.class);
            NotificationChannel channel = new NotificationChannel(
                    "channel_id",
                    "前台通知渠道名称",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            manager.createNotificationChannel(channel);
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentTitle("Binder服务端")
                .setContentText("测试Binder的前台Service");

        startForeground(NOTIFICATION_ID, builder.build());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.e("Binder的服务", "在Service做耗时任务的话,请使用子线程,因为Service是在主线程运行的");
                Log.e("Binder的服务", "此时的线程:" + Thread.currentThread().getName());
            }
        }).start();
        return START_STICKY;
    }
}

主页面:
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
完整代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tvStartService = findViewById(R.id.tv_startService);
        TextView tvStopService = findViewById(R.id.tv_stopService);
        tvStartService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, MyService.class);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    startForegroundService(intent);
                } else {
                    startService(intent);
                }
            }
        });
        tvStopService.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, MyService.class);
                stopService(intent);
            }
        });
    }
}
注意:

需要在AndroidManifest.xml文件中添加这个权限:

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

不然会报错:

Permission Denial: startForeground from pid=16363, uid=10134 requires android.permission.FOREGROUND_SERVICE

同时在此文件里面注册完善MyService文件

<service
     android:name=".MyService"
     android:enabled="true"
     android:exported="true">
     <intent-filter>
           <action android:name="com.shsany.mybinderservice"/>
     </intent-filter>
</service>

此时配置好之后,要记得Build一下项目,这样Android Studio会自动生成AIDL的代码
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
生成的代码:
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

客户端

在客户端需要配置的和服务端的步骤方法一样,不再叙述。

注意:

在客户端的AIDL文件不要自己重新写,要从服务端复制过来,保证两边是一样的。

服务端

【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

客户端

【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

这两个端的这个文件无论是包名还是里面的代码都要一样的,所以直接复制最好。

客户端命名为MyBinder,只有一个文件

【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

MainActivity代码

【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
完整代码:

public class MainActivity extends AppCompatActivity {
    private IMyService mMyService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tvGetData = findViewById(R.id.tv_getBinderData);

        Intent intent = new Intent();
        intent.setAction("com.shsany.mybinderservice");
        intent.setPackage("com.shsany.mybinderservice");
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

        tvGetData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    // 在使用服务端方法时,先判断服务是否可用
                    if (mMyService != null) {
                        long currentTime = mMyService.getCurrentTimestamp();
                        Log.e("Binder数据:", "从服务端接收到的时间戳:" + currentTime);
                    } else {
                        Log.e("Binder数据:", "无法连接到服务端");
                    }
                } catch (Exception e) {
                    Log.e("Binder错误:", e.getMessage());
                }
            }
        });
    }

    private final ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //远程Service绑定
            Log.e("Binder数据:", "已经连接到服务端");
            mMyService = IMyService.Stub.asInterface(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            //Service被意外销毁
            Log.e("Binder数据:", "服务端被意外销毁");
            mMyService = null;
        }
    };
}
测试

首先需要先启动服务端
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
然后再启动客户端
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
此时连接到服务端之后,服务端的显示
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
然后再客户端上面调用getCurrentTimestamp方法获取数据:
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
此时再看服务端
【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
至此,一个简单的AIDL使用Binder跨进程通信就完成了。文章来源地址https://www.toymoban.com/news/detail-467329.html

到了这里,关于【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android:AIDL简单介绍+传递简单数据+传递复杂数据

    对于AIDL的学习,这些也只能说是我在学习中的理解,有理解不到位或者错的地方也欢迎指正。 AIDL的目的就是实现进程之间的通信, 尤其是在涉及多进程并发情况下的进程间通信 。可以将aidl理解为两个进程之间的桥梁,并制定规则,使其传输特定数据。 1.AIDL支持的数据类型

    2024年02月21日
    浏览(41)
  • Android AIDL基本使用

    AIDL是Android多进程通讯方式一种。 如要使用 AIDL 创建绑定服务,请执行以下步骤: 创建 .aidl 文件 此文件定义带有方法签名的编程接口。 实现接口 Android SDK 工具会基于您的  .aidl  文件,使用 Java 编程语言生成接口。此接口拥有一个名为  Stub  的内部抽象类,用于扩展  B

    2024年02月09日
    浏览(37)
  • AIDL 详细介绍及使用

    一、AIDL是什么?  AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码。从某种意义上说AIDL其实是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据

    2024年04月14日
    浏览(24)
  • Android 使用AIDL传输超大型文件

    最近在写车载Android的第5篇视频教程「AIDL的实践与封装」时,遇到一个有意思的问题,能不能通过AIDL传输超过 1M 以上的文件? 我们先不细究,为什么要用AIDL传递大文件,单纯从技术的角度考虑能不能实现。众所周知,AIDL是一种基于Binder实现的跨进程调用方案,Binder 对传输

    2024年02月10日
    浏览(53)
  • Android中AIDL的简单使用(Hello world)

    AIDL:Android Interface Definition Language(Android接口定义语言) 作用:跨进程通讯。如A应用调用B应用提供的接口 A应用创建aidl接口,并且创建一个Service来实现这个接口(在onBind方法里面return我们这个接口的实例)。 把A应用创建的aidl文件原封不动的搬至B应用中(注意包名类名都

    2024年02月11日
    浏览(50)
  • [DEMO] Android Binder 的使用

    The Android binderfs Filesystem — The Linux Kernel documentation Android Binder 是一种 IPC 机制,IPC 键值/标识 是一个字符串,收发双方通过 键值/标识 建立通讯路径。 Binder 是通过模板类实现的,因此使用起来并不是那么简明通俗,如果没有demo可以参考的话是需要琢磨好一阵子。 class IInt

    2024年02月13日
    浏览(40)
  • [Android AIDL] --- AIDL原理简析

    上一篇文章已经讲述了如何在Android studio中搭建基于aidl的cs模型框架,只是用起来了,这次对aidl及cs端如何调用的原理进行简单分析 AIDL 文件可以分为两类。 一类是用来定义接口方法,声明要暴露哪些接口给客户端调用; 一类用来声明实现了 Parcelable 接口的数据类型,以供其

    2024年02月10日
    浏览(44)
  • [Android AIDL] --- AIDL工程搭建

    AIDL(Android Interface Definition Language)是一种 IDL 语言,用于生成可以在 Android 设备上两个进程之间进行进程间通信(IPC)的代码。 通过 AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法,从而满足进程间通信的需求。通常,暴露方法给其他应用进行调用的

    2024年02月10日
    浏览(49)
  • [Android AIDL系列 1] 手动编译aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口

    AIDL文件在Android系统上应用广泛,和底层的Binder机制紧密关联。 在Android源码或者Android Studio中通常是自动编译aidl文件,生成对应语言的接口文件。 做应用层Java开发,aidl和binder封装的比较“干净”,不用太多的涉及binder的调用细节,也不用太关心aidl的编译过程。 如果是做中

    2024年02月08日
    浏览(44)
  • Android:AIDL实战详解

    AIDL:Android Interface Definition Language AIDL是为了实现进程间通信而设计的Android接口语言 Android进程间通信有多种方式,Binder机制是其中最常见的一种 AIDL的本质 就是基于对Binder的运用从而实现进程间通信 这篇博文从实战出发,用一个尽可能精简的Demo,实现两个App (也是两个进程:

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包