Android中AIDL的简单使用(Hello world)

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

AIDL:Android Interface Definition Language(Android接口定义语言)

作用:跨进程通讯。如A应用调用B应用提供的接口

代码实现过程简述:

A应用创建aidl接口,并且创建一个Service来实现这个接口(在onBind方法里面return我们这个接口的实例)。

把A应用创建的aidl文件原封不动的搬至B应用中(注意包名类名都要一样),B应用bindService的方式来绑定A应用创建的这个Service,从而调用A应用提供的接口。

实现:

一、A应用(服务端)(提供接口被调用者):

1、创建AIDL文件:

Android Studio在项目main目录右键新建,找到AIDL,它会帮我们创建文件夹和文件,默认名字IMyAidlInterface,开发者根据需求修改名字

里面有:

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    //上面这个是新建的时候自己生成的,可以去掉,我们自己新建以下方法,一个get(从服务端取值),一个set(传值给服务端)
    String getHelloString();
    void setHelloString(String string);
}

写了之后make project一下,会自动生成IMyAidlInterface类。

2、创建service:(不需要A应用手动startService,B应用bindService的时候这个服务就会自动起来)

public class AidlTestService extends Service {

    private String hello;

    @Override
    public void onCreate() {
        super.onCreate();
        hello = "hello";
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }

    public class MyBinder extends IMyAidlInterface.Stub{

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
            Log.i("xaeHu", "basicTypes: \nanInt = "+anInt
                    +"\naLong = "+aLong
                    +"\naBoolean = "+aBoolean
                    +"\naFloat = "+aFloat
                    +"\naDouble = "+aDouble
                    +"\naString = "+aString
            );
        }

        @Override
        public String getHelloString() throws RemoteException {
            return hello;
        }

        @Override
        public void setHelloString(String string) throws RemoteException {
            hello = string;
        }
    }
}

3、清单文件声明这个service:(网上有说这个name需要全称,我这里实际没有用全称也能绑定成功)

<service android:name=".AidlTestService"
            android:enabled="true"
            android:exported="true" />

A应用的工作完成,接下来是B应用如何使用这个接口:

二、B应用(客户端)(接口调用者):

1、清单文件声明A应用的包名:(Android11新增,如果项目targetSdk>=30的话需要这一步,否则bindService是调不起来A应用的服务的)(这个坑网上很多AIDL的教程博客都没有说)

   <!--  配置服务端的包名-->
    <queries>
        <package android:name="com.example.myapplication" />
    </queries>

2、把A应用创建的AIDL文件包括A应用包名一起复制到B应用main目录下:

我这边A应用包名是“com.example.myapplication”,B应用包名是“com.example.myapplication2”

Android中AIDL的简单使用(Hello world)

 注意aidl的包名要与A应用一致,否者调用方法的时候会报异常:java.lang.SecurityException: Binder invocation to an incorrect interface

放进来之后make project一下,会自动生成IMyAidlInterface类。

3、绑定服务,调用aidl接口提供的方法:

比如直接在MainActivity的onCreate里面去绑定服务:

public class MainActivity extends AppCompatActivity{
    private IMyAidlInterface myAidlInterface;
    private final ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

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

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

        //点击按钮一去绑定服务
        findViewById(R.id.btn1).setOnClickListener(v -> {
           Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.example.myapplication","com.example.myapplication.AidlTestService"));
            boolean re = bindService(intent, connection, Context.BIND_AUTO_CREATE);
            Log.i("xaeHu", "bindService: "+re);
        });

        //点击按钮2调用set方法
        findViewById(R.id.btn2).setOnClickListener(v -> {
            if(myAidlInterface != null){
                try {
                    myAidlInterface.setHelloString("hello world");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }else {
                Log.e("xaeHu", "btn2 onclick: myAidlInterface == null");
            }
        });

        //点击按钮3调用get方法
        findViewById(R.id.btn3).setOnClickListener(v -> {
            if(myAidlInterface != null){
                try {
                    Toast.makeText(this, myAidlInterface.getHelloString(), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }else {
                Log.e("xaeHu", "btn3 onclick: myAidlInterface == null");
            }
        });
    }

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

简单的AIDL调用就搞定啦。

进阶:

上面的演示是传递基本数据类型为参数的,接下来通过AIDL传递对象

先在aidl文件夹中创建实体对象文件,再在java文件夹中创建实体类,不然的话在java中创建了实体类,再在aidl中创建相同的名字会提示错误。

A应用中:

比如我们创建Student对象,在aidl文件夹中就是Student.aidl,里面代码很简单:

package com.example.myapplication;

parcelable Student;

然后再在java中创建Student.java,注意需要实现Parcelable:

public class Student implements Parcelable {
    private int id;
    private String name;
    private int age;
    private int sex;

    public Student() {
    }

    public Student(int id, String name, int age, int sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    protected Student(Parcel in) {
        id = in.readInt();
        name = in.readString();
        age = in.readInt();
        sex = in.readInt();
    }

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel in) {
            return new Student(in);
        }

        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getSex() {
        return sex;
    }

    public int getId() {
        return id;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeInt(sex);
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
}

在aidl接口中添加方法:(注意addStudent(in Student student);参数需要添加in表示接收参数,另外有out、inout)

// IMyAidlInterface.aidl
package com.example.myapplication;

import com.example.myapplication.Student;
// Declare any non-default types here with import statements

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    String getHelloString();
    void setHelloString(String string);

    void addStudent(in Student student);
    Student getStudent(int id);
}

服务中实现这两个方法:

private Map<Integer,Student> studentMap;

@Override
public void addStudent(Student student) throws RemoteException {
    Log.i("xaeHu", "addStudent: "+student);
    if(studentMap == null){
        studentMap = new HashMap<>();
    }
    studentMap.put(student.getId(), student);
}

@Override
public Student getStudent(int id) throws RemoteException {
    if(studentMap != null){
        Student student = studentMap.get(id);
        Log.i("xaeHu", id + " -> getStudent: "+student);
        return student;
    }
    Log.i("xaeHu", id + " -> getStudent: null");
    return null;
}

B应用:

同样的把aidl文件和类搬过来,注意实体对象的包名需要与A应用包名一致:

Android中AIDL的简单使用(Hello world)

然后同样的,在绑定服务之后就可以调用了:

myAidlInterface.addStudent(new Student(1,"student1",26,0));
myAidlInterface.addStudent(new Student(2,"student2",27,1));

Log.i("xaeHu", "getStudent1: "+myAidlInterface.getStudent(1));
Log.i("xaeHu", "getStudent2: "+myAidlInterface.getStudent(2));

 文章来源地址https://www.toymoban.com/news/detail-515473.html

完。

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

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

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

相关文章

  • windows下cmake的小白级入门使用教程(hello world)

    想学习cmake,基于惯性思维,想先跑通一个“hello world”的例子,奈何网上教程一大把,有用的教程破费功夫寻找。大部分教程都没有从新电脑(重装系统后的电脑)的角度讲述步骤。 为了得到干净的电脑环境,研究了一段时间VMware虚拟机,并写了几篇文章,感兴趣的读者可移步

    2024年02月14日
    浏览(42)
  • js简介以及在html中的2种使用方式(hello world)

    javascript :是一个跨平台的脚本语言;是一种轻量级的编程语言。 JavaScript 是 Web 的编程语言。所有现代的 HTML 页面都使用 JavaScript。 HTML: 结构 css: 表现 JS: 行为 HTML+CSS 只能称之为静态网页,加入js网页则有了灵魂称之为动态网页 脚本语言的特点: 不能独立运行,要依赖

    2024年02月12日
    浏览(50)
  • 使用 GNU 汇编语法编写 Hello World 程序的三种方法

    本篇我们使用汇编来写一个经典的  Hello world  程序。 运行环境: OS:Ubuntu 18.04.5 LTS x86-64 gcc:version 4.8.5 在用户空间编写汇编程序输出字符串,有三种方法: 调用C库函数  printf 使用软中断  int 0x80 使用  syscall 系统调用 下面对三种方法,分别进行说明。 为了更好的理解汇

    2024年02月06日
    浏览(56)
  • 编程笔记 Golang基础 007 第一个程序:hello world 使用Goland

    开始在Goland环境中编程go语言代码啦。 打开GoLand软件。 选择 “File”(文件)菜单,然后点击 “New Project”(新建项目)或使用快捷键 Ctrl+Shift+A 并搜索 “New Project”。 在新建项目向导中,选择 “Go” 并点击 “Next” 按钮。 配置项目设置: 为项目选择一个合适的保存位置。

    2024年02月20日
    浏览(42)
  • 使用Microsoft Visual Studio 2022创建C语言项目并打印Hello World

    安装Visual Studio 安装C++环境 创建新项目 选择C++语言 创建空项目 填入自己的项目名称 新建源文件 9. 添加新项 10. 选择C++文件 将创建的文件名后缀改为.C文件 11. 填入代码 运行调试 12. 输出结果到控制台

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

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

    2024年02月09日
    浏览(35)
  • Android 使用AIDL传输超大型文件

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

    2024年02月10日
    浏览(50)
  • Android Binder常用案例使用分析,跨进程通信aidl

    service组件的binderService获取binder通信。 servicemanager.getService方法获取相关服务。 本质上都是IBinder通信。 客户端:使用intent,启动服务端的service,使用binderservice,在onServiceConnected回调方法中获取服务端的实际binder对象。使用aidl中的接口调用服务端的方法即可。 服务端:定义

    2024年02月07日
    浏览(44)
  • 【C快学-C语言程序设计(基础篇)】从VSCode中使用C编写我的第一个Hello world

    简介:本专栏是一个C语言基础入门知识学习的一个专栏 面向:广大C友 工具:VSCODE 博主:一个友好且宠粉的博主,送书活动小专栏,不定期抽奖送图书给粉丝 社区:🦈山鱼社区 我这里是使用超级强大的vscode来进行C语言的学习的,因为vscode有着许多好用且方便的插件,能够

    2024年02月13日
    浏览(47)
  • ROS Hello World

    ROS 系列学习教程(总目录) 万物始于Hello World,为了体验ROS,使用Hello World介绍ROS的简单使用。 首先需要创建工程,流程为: 创建工作空间目录(即工程根目录,注意此时还不是ROS工作空间,只是一个目录) 初始化工作空间(即把当前目录初始化为一个ROS工作空间) 创建功能

    2024年02月06日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包