Android中实现跨进程通信(IPC)的几种方式(二)

本文介绍如何使用Android接口定义语言(AIDL)实现Android平台上的跨进程通信(IPC),包括创建.aidl文件、实现 Parcelable 接口和服务端客户端通信的具体步骤。

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

Android中实现跨进程通信(IPC)的几种方式(二)

    在上一篇文章中介绍了什么是多进程,为什么需要多进程,多进程的优缺点等。这篇我们将会使用AIDL来实现跨进程通信。

1.什么是AIDL

    AIDL全称是Android接口定义语言 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。

2. 创建.aidl文件

    AIDL 使用简单语法,使您能通过可带参数和返回值的一个或多个方法来声明接口。 参数和返回值可以是任意类型,甚至可以是其他 AIDL 生成的接口。

3. 创建客户端服务端进行通信的实体类,并实现Parcelable接口。
4. 创建aidl文件

5. 创建于实体类对应的aidl文件

6. 创建通信接口aidl文件

7默认情况下,AIDL 支持下列数据类型:

默认情况下,AIDL 支持下列数据类型:

Java 编程语言中的所有原语类型(如 int、long、char、boolean 等等)
String
CharSequence
List
    List 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 可选择将 List 用作“通用”类(例如,List)。另一端实际接收的具体类始终是 ArrayList,但生成的方法使用的是 List 接口。

Map
    Map 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 不支持通用Map 另一端实际接收的具体类始终是 HashMap,但生成的方法使用的是 Map 接口。

    您必须为以上未列出的每个附加类型加入一个 import 语句,即使这些类型是在与您的接口相同的软件包中定义。

8. 注意事项

     非基本的数据类型都需要导入包,即使他们在同一个包里面。
    在方法参数中,除了基本数据类型,其他的数据类型都需要标上 in(输入) out(输出) inout(输入输出)

  1. build project,然后找到build/generated/source/aidl目录下面生成的Java文件
9实现服务端代码
package com.example.huangjie.ipc;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

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


/**
 * Created by huangjie on 2018/5/22.
 */

public class AidlService extends Service {
    private ArrayList<Book> bookList;
    private IBinder mBinder = new BookManager.Stub() {
        @Override
        public void addBook(Book book) throws RemoteException {
            bookList.add(book);
        }

        @Override
        public List<Book> getBookList() throws RemoteException {
            return bookList;
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        bookList = new ArrayList<>();
        bookList.add(new Book("ID123", "Android开发艺术探索"));
        bookList.add(new Book("ID124", "剑指offer Java版"));

    }


}

声明服务端Servce

 <service
            android:name=".AidlService"
            android:process=":test">
        </service>
10编写客户端绑定service代码
package com.example.huangjie.ipc;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.List;


public class MainActivity extends AppCompatActivity {


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


        ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {

                BookManager bookManager = BookManager.Stub.asInterface(service);

                try {
                    List<Book> bookList = bookManager.getBookList();

                    Toast.makeText(getApplicationContext(), "来自服务端的数据" + bookList.toString(), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };

        Intent intent = new Intent(this, AidlService.class);

        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }


}
总结:实现AIDL跨进程通信步骤:
  1. 实现服务端于客户端通信实体类并实现Parcelable接口
  2. 在项目 src/ 目录中加入 .aidl 文件。
  3. 声明一个 IBinder 接口实例(基于 AIDL 生成)。
  4. 实现 ServiceConnection。
  5. 调用 Context.bindService(),以传入您的 ServiceConnection 实现。
  6. 在您的 onServiceConnected() 实现中,您将收到一个 IBinder 实例(名为 service)。调用BookManager bookManager = BookManager.Stub.asInterface(service) ,以将返回的参数转换为BookManager 类型。
  7. 调用您在接口上定义的方法。您应该始终捕获 DeadObjectException 异常,它们是在连接中断时引发的;这将是远程方法引发的唯一异常。
  8. 如需断开连接,请使用您的接口实例调用 Context.unbindService()。

代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值