Aidl 实战解析,进程间通信

本文详细介绍了一种Android进程间通信方式AIDL的使用方法,包括创建序列化的数据类型、建立AIDL文件、生成服务端及客户端代码等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

众所周知,AIDL是进程间通信很常用的一种通信方式,很多时候你总会觉得它非常复杂而又乱

其实,你写一个demo你就懂了

而且最好的理解方式也是你自己亲手写一个demo!

下面我们通过一个最简单的demo来所说AIDL到底是怎么使用的

第一步 创建一个你要在进程间传递的数据类型,并且让这个数据类型implement安卓的两种序列化方式之一,Serializable或者Parcelable!否则,你的这个数据是没有办法在进程间通信传递的!

关于这Serializable和Parcelable的序列化,可以自己在百度了解一下

下面我建立了一个自己的数据类型book~   继承Parcelable

项目结构如下


额,项目结构要注意,后面你建立aidl的文件项目结构要跟这个一样才行的

book.java的代码如下

package come.example.administrator.myapplication.aldl;

import android.os.Parcel;
import android.os.Parcelable;

public class book implements Parcelable {
    private String bookname;

    protected book(Parcel in) {
        bookname = in.readString();
    }

    public book(String name){
        bookname=name;
    }

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

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

    public String getBookname() {
        return bookname;
    }

    public void setBookname(String bookname) {
        this.bookname = bookname;
    }

    @Override
    public int describeContents() {

        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(bookname);
    }
}
在这里要注意下,其中
@Override
    public int describeContents() {

        return 0;
    }


@Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(bookname);
    }
都是你继承parceable自动实现的方法,这是用来将数据类型序列化的方法,而且这些方法还分三种,这里默认的只是in的方法,还有out和inout方法没有,感兴趣的可以自己百度一下


然后建好这个数据类之后,我们开始第二步


第二步:创建第一步数据类型的映射aidl文件

具体步骤:先建立一个跟java文件夹同级的文件夹aidl,目录结构如下


当然,也有更简单的方法,那就是你鼠标右键new的时候有一个这样选项


选择这个选项,android studio会自动给你在java同级别建立aldl文件夹,还建立其中的包结构

刚才说过,在这第二步,我们要建立一个book的映射aidl文件,其实就是在java同级别的aidl文件夹下建立一个包路径名跟前面book.java一样的book.aidl

这里有些绕口,不过你看一下最后的目录结构就知道怎么回事了


可以看到,你要建立一个跟下面红色箭头book文件对应的,但是在aidl文件下下面的book.aidl文件

在这里要特别注意,这个文件路径要跟下面的book.java一样,包名都是一样的,注意到了吧

然后建立book.aidl文件之后,它的内容是这样的:

// bookd.aidl
package come.example.administrator.myapplication.aldl;

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

parcelable book;
嗯,你看到了,其实就一句话,你加一句parcelable book就可以了


第三步,建立具体操作数据,也就是操作那个book.java的aidl文件

在这里,我建造的是bookManger.aidl,里面只有两个方法addbook,和getListbook

目录结构如下:

内容如下

// bookManger.aidl
package come.example.administrator.myapplication;
import come.example.administrator.myapplication.aldl.book;

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

interface bookManger {
    /**
     * 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);
    void addbook(in book book);
    List<book> getListBook();
}
在这里也有一点要注意,那就是

import come.example.administrator.myapplication.aldl.book;
你要手动import 这个book进去


这样,建造aidl方面工作就完成了,


第四步,生成系统用的aidl操作文件,其实就一个步骤,



你rebuild 一下你的工程,要是没有报错,你会发现在你工程的这个路径下会多出一个文件夹


要是发现这个文件夹那就可以了,然后不去管它


第五步  构造你通信用的服务端,

我在这里构造了一个service,这里路径没有规定,随意放就可以,我是这样放的


里面我是这样写的

package come.example.administrator.myapplication.aldl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import come.example.administrator.myapplication.bookManger;

import java.util.ArrayList;
import java.util.List;

public class aldlService extends Service {

    private ArrayList<book> mbook;

    /**
     * 创建生成的本地 Binder 对象,实现 AIDL 制定的方法
     */
    private IBinder mIBinder = new bookManger.Stub() {


        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public void addbook(book book) throws RemoteException {
            mbook.add(book);
        }

        @Override
        public List<book> getListBook() throws RemoteException {
            return mbook;
        }
    };



    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        mbook = new ArrayList<>();
        return mIBinder;
    }
}


这样就可以了,哦, 对了,别忘了在manifest文件注册你的service啊

<service
                android:name=".aldl.aldlService"
                android:enabled="true"
                android:exported="true"
                android:process=":aidl"/>



第六步   创建你的客户端

其实也就是调用这个service,并且与这个service连接,拿到bindservice中的IBinder就可以了

我这里实现简单通信,代码如下

package come.example.administrator.myapplication.aldl;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import come.example.administrator.myapplication.R;
import come.example.administrator.myapplication.bookManger;

import java.util.ArrayList;

public class AidlActivity extends AppCompatActivity {
    ArrayList<book> mbook;
    int bookindex=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);
        Intent intent1 = new Intent(getApplicationContext(), aldlService.class);
        bindService(intent1, mConnection, BIND_AUTO_CREATE);
    }

    public void getClick(View v) throws RemoteException {
        switch (v.getId()){
            case R.id.addbook:
                mAidl.addbook(new book("新书"+bookindex));
                bookindex++;
                Toast.makeText(getApplicationContext(),"新书添加成功",Toast.LENGTH_SHORT).show();
                break;
            case R.id.getbook:
                mbook= (ArrayList<book>) mAidl.getListBook();
                Toast.makeText(getApplicationContext(),"新书添加成功"+mbook.get(mbook.size()-1).getBookname(),Toast.LENGTH_SHORT).show();
                break;
        }
    }

    private bookManger mAidl;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
            mAidl = bookManger.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mAidl = null;
        }
    };
}
其实要注意的就是,getclick是我按钮的点击事件,点击的时候,拿到下面mAidl,就可以使用我们刚才定义的bookManger定义的方法并且使用了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值