AIDL介绍以及简单使用

目录

  • 一. AIDL 介绍.
  • 二. AIDL简单应用.
    • Aidl_Server端
    • Aidl_Client端
  • 三.注意事项

一. AIDL 介绍.

 AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,可以是一个在Android设备上运行的两个进程使用内部通信进程进行交互。

如果你想在一个进程中(例如在一个Activity中)访问另一个进程中(例如service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

稍微了解下几个常见的名词(IPC,匿名共享内存,Binder,Aidl,消息,广播,ContentProvider,Intent):

IPC是一种概念,即进程间通信;其它几个都是Android里的概念;

匿名共享内存(Anonymous Shared Memory):其作用之一即通过Binder进程间通信机制来实现进程间的内存共享。

Binder:Binder是对IPC的具体实行,是IPC的一种具体实现.其本质也是调用系统底层的共享内存实现.

AIDL:进程间的通信,速度快(系统底层直接是共享内存),性能稳,效率高,一般进程间通信就用它. AIDL是Binder机制向外提供的接口,目的就是为了方便对Binder的使用;

消息(Messager):Messenger本质也是AIDL,只是进行了封装,开发的时候不用再写.aidl文件,效率应该是和Aidl是一样的,与Aidl的区别在于Messager是线程安全的,而Aidl是非线程安全的,所以Aidl在使用的时候应该注意这个问题;

广播(BroadcastReceiver):只要注册了广播,都能收到,有点范围广,缺点速度慢必须在一定时间完成处理操作,同其他Android四大组件一样,都不能执行耗时操作;

ContentProvider:暴露app的数据访问接口,让其他应该访问app数据.同时也能通过ContentProvider来访问第三方的一些app数据(如通讯录,日历等暴露接口的应用);

Intent:Intent是最高层级的封装,实质是封装了对Binder的使用,当然Intent也常常在同一进程中调用,只是把两种方式封装在一起了.

二. AIDL简单应用.

编写两个app应用程序,一个实现Aidl传递的Server端,一个实现Aidl的Client端:
aidl的Server端,接收Client端传过来的两个int值,定义一个加法计算的逻辑规则, 并返回 两个int数之和, return num1 + num2;
aidl的Client端,从界面用户输入两个int数,点击绑定Server端服务,点击计算,调用Server端加法逻辑,将返回结果 输入到用户界面展示,两数之和.

Aidl_Server端

// IImoocAIDL.aidl
 package com.example.administrator.aidl_server.service;

// Declare any non-default types here with import statements

interface IImoocAIDL {
     //计算num1 + num2
        int add(int num1,int num2);
}

编译后会生成

public interface IImoocAIDL extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.example.administrator.aidl_server.service.IImoocAIDL {
            ...
            private static class Proxy implements com.example.administrator.aidl_server.service.IImoocAIDL {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public int add(int num1, int num2) throws android.os.RemoteException {
                ...
            }

            ...
        }
            ...
    }
}

//om.example.administrator.aidl_server.IRemoteService

public class IRemoteService extends Service {
    public static final String TAG = "IRemoteService";
    //客户端绑定service时会执行
    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }

    private IBinder iBinder = new IImoocAIDL.Stub() {
        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.e(TAG,"收到了来自客户端的请求" + num1 + "+" + num2 );
            return num1 + num2;
        }

    };
}

//AndroidManifest.xml

<application
    ...
        <service android:name=".IRemoteService"
            android:process=":remote"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.administrator.aidl_server"/>
            </intent-filter>
        </service>
    ...
</application>

Aidl_Client端

com.example.administrator.aidl_client.MainActivity
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    private EditText et_send_input,nub_1,nub_2;
    private TextView tv_send;
    private TextView tv_bind;
    private IImoocAIDL iImoocAIDLService;

    private ServiceConnection conn = new ServiceConnection() {

        //绑定服务,回调onBind()方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iImoocAIDLService = IImoocAIDL.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iImoocAIDLService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindService();

        et_send_input = findViewById(R.id.et_send_input);
        nub_1 = findViewById(R.id.nub_1);
        nub_2 = findViewById(R.id.nub_2);
        tv_send = findViewById(R.id.tv_send);
        tv_bind = findViewById(R.id.tv_bind);

        tv_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    int nub1 = Integer.parseInt(nub_1.getText().toString().trim());
                    int nub2 = Integer.parseInt(nub_2.getText().toString().trim());

                    int result = iImoocAIDLService.add(nub1,nub2);
                    et_send_input.setText(result+"");
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });

        tv_bind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bindService();
                Log.e(TAG,"bindService"+iImoocAIDLService);
            }
        });
    }

    private void bindService() {
        Intent intent = new Intent();
        //绑定服务端的service
        intent.setAction("com.example.administrator.aidl_server.IRemoteService");
        //新版本(5.0后)必须显式intent启动 绑定服务
        intent.setComponent(new ComponentName("com.example.administrator.aidl_server","com.example.administrator.aidl_server.IRemoteService"));
        //绑定的时候服务端自动创建
        bindService(intent,conn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/nub_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="number" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="+" />

        <EditText
            android:id="@+id/nub_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="number" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="=" />

        <EditText
            android:id="@+id/et_send_input"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="number" />
    </LinearLayout>

    <TextView
        android:id="@+id/tv_bind"
        android:layout_width="200dp"
        android:layout_height="55dp"
        android:layout_gravity="center"
        android:layout_marginBottom="15dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="bind" />

    <TextView
        android:id="@+id/tv_send"
        android:layout_width="200dp"
        android:layout_height="55dp"
        android:layout_gravity="center"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="计算" />

</LinearLayout>

三.注意事项

如果运行中报错:

aidl Method threw ‘java.lang.SecurityException‘ exception.

需要 确保客户端的aidl文件包名要与服务端的包名一样.也就是本项目中的IImoocAIDL.aidl文件包名一致.



[1] 参考资料: https://blog.csdn.net/jinxinliu1/article/details/70174591

原文地址:https://www.cnblogs.com/bugzone/p/aidl.html

时间: 2024-11-17 14:59:46

AIDL介绍以及简单使用的相关文章

Android开发之IPC进程间通信-AIDL介绍及实例解析

一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:   2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身:linux除了支持Unix早期

AIDL介绍和实例讲解

前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface Definition Language, Android接口定义语言). 网上看了几篇关于AIDL的文章,写得都很不错,不过例子构造大多略微复杂: 建立两个Android项目,一个是client,一个是server(提供service). 这篇文章将通过一个项目来介绍AIDL用法,包含了servic

Android反编译工具介绍与简单实用方法

Android反编译工具介绍与简单实用方法 Android反编译的目的无非就是为了看到APK的xml.资源和代码: 得到代码的方式:直接解压APK文件 --> 得到classes.dex文件 --> 使用 dex2jar classes.dex classes.jar生成jar文件 --> [可选的解压jar文件] -->使用XJad或者JDCompiler查看源代码 得到XML的方式: 方式1:直接解压APK文件 --> 通过axmlprinter工具查看XML文件(这种方

进击的Python【第十二章】:mysql介绍与简单操作,sqlachemy介绍与简单应用

进击的Python[第十二章]:mysql介绍与简单操作,sqlachemy介绍与简单应用 一.数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量.所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来

玩转web之servlet(六)---session介绍及简单使用(登录验证中保存信息)

在浏览器与服务器进行交互时,往往需要把涉及到的一些数据保存下来,这时就需要使用cookie或session进行状态管理. 这篇文章先来说说session怎么用,首先在servlet中创建一个session来保存信息,举个例子,在做登陆验证时,如果登陆成功,需要将用户的信息保存到session中,怎么保存呢?下面给出代码: public class Login_Do extends HttpServlet { String order_name = ""; String order_pa

Json.Net的介绍与简单实用(兼容2.0/3.0/3.5/4.5/RT)

本文的前提是你已经熟悉Json,如果您还不知道什么是Json是什么,请自行查看维基百科. 一.Json.Net是什么? Json.Net是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Linq To JSON可以快速的读写Json,通过JsonSerializer可以序列化你的.Net对象.让你轻松实现.Net中所有类型(对象,基本数据类型 等)和Json的转换. 二.为什么使用Json.Net? 我们知道在.Net中内置了读写Json

(三)AJAX基本介绍和简单实例03

AJAX基本介绍和简单实例03-----Ajax与数据库的动态应用 初始界面: 选择所有用户后显示的界面: 查询姓名为杜森的客户,结果如下: Demo03.html代码如下: <html> <meta http-equiv="content-type" content="text/html" charset="utf-8"/> <head> <style> body { background:#CC

WebRTC介绍及简单应用

WebRTC介绍及简单应用 WebRTC,即Web Real-Time Communication,web实时通信技术.简单地说就是在web浏览器里面引入实时通信,包括音视频通话等. WebRTC实时通信技术介绍 如何使用 媒体介绍 信令 STUN和TURN介绍 对等连接和提议/应答协商 数据通道 NAT和防火墙穿透 简单应用 其它 WebRTC实时通信技术介绍 WebRTC实现了基于网页的语音对话或视频通话,目的是无插件实现web端的实时通信的能力. WebRTC提供了视频会议的核心技术,包括

消息队列介绍、RabbitMQ&amp;Redis的重点介绍与简单应用

消息队列介绍.RabbitMQ.Redis 一.什么是消息队列 这个概念我们百度Google能查到一大堆文章,所以我就通俗的讲下消息队列的基本思路. 还记得原来写过Queue的文章,不管是线程queue还是进程queue他都是一种消息队列.他都是基于生产者消费者模型来处理消息. Python中的进程queue,是用于父进程与子进程,或者同属于一个父进程下的多个子进程之间进行信息交互.注意这种queue只能在同一个python程序下才能用,如果两个python程序,或者Python和别的什么程序,