当前位置: 首页 > 编程笔记 >

Android使用AIDL实现两个App间通信

锺离旻
2023-03-14
本文向大家介绍Android使用AIDL实现两个App间通信,包括了Android使用AIDL实现两个App间通信的使用技巧和注意事项,需要的朋友参考一下

今天开发了一个功能,通过Android的AIDL机制完成两个app间的通信。功能需求很简单,一个客户端app,叫做client,一个服务端app叫orderManager;客户端负责展示订单列表,并且可以向服务端添加订单;服务端负责管理订单,可以对外提供订单信息。

闲言少叙,下面直接上代码。

1、编写bean类。

首先在client中定义OrderBean类,字段很简单,注意需要实现Parcelable接口

package com.example.wang.client.bean;

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

public class OrderBean implements Parcelable{
 private String id;
 private String name;
 private int amount;

 public OrderBean(){}

 public OrderBean(String id, String name, int amount) {
 this.id = id;
 this.name = name;
 this.amount = amount;
 }

 protected OrderBean(Parcel in) {
 id = in.readString();
 name = in.readString();
 amount = in.readInt();
 }

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

 @Override
 public OrderBean[] newArray(int size) {
  return new OrderBean[size];
 }
 };
 @Override
 public int describeContents() {
 return 0;
 }

 @Override
 public void writeToParcel(Parcel dest, int flags) {
 dest.writeString(id);
 dest.writeString(name);
 dest.writeInt(amount);
 }
 //get/set方法略
}

2、定义aidl文件。aidl文件的存放位置在Android Studio中一般存放在如下路径:
client/src/aidl/…

 // OrderBean.aidl
package com.example.wang.client.bean;//存放的包路径同bean类
parcelable OrderBean;//通信用到的Parcelable需要声明,并且使用小写的parcelable

// IBookManager.aidl
package com.example.wang.client.aidl;

import com.example.wang.client.bean.OrderBean;//除了系统提供的对象,都需要明确导入

interface IOrderManager {
 List<OrderBean> getAll();
 void add(in OrderBean bean);
}

3、定义布局文件,编写MainActivity。这个很简单,Button和RecyclerView结合即可:

#activity_main.xml - 主页面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center_horizontal"
 android:layout_marginTop="5dp"
 android:text="订单管理"
 android:textSize="20dp"/>
 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:padding="5dp">
 <Button
  android:id="@+id/search_button"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textSize="15dp"
  android:text="刷新订单"/>
 <Button
  android:id="@+id/add_button"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textSize="15dp"
  android:text="添加订单"/>
 </LinearLayout>
 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 />
</LinearLayout>

还要写一个item_order.xml,用于RecyclerView的展示,很简单,此处略过。

//MainActivity.java
package com.example.wang.client;
...
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
 private List<OrderBean> orderList;
 private IOrderManager orderManager;
 //UI
 private Button search_button;
 private Button add_button;
 private RecyclerView recyclerView;
 private OrderAdapter adapter;

 ServiceConnection conn = new ServiceConnection() {//这个最重要,用于连接Service
 @Override
 public void onServiceConnected(ComponentName name, IBinder service) {
  Log.i("MainActivity.conn","@@ onServiceConnected name="+name);
  IOrderManager manager = IOrderManager.Stub.asInterface(service);
  orderManager = manager;
  refreshOrderList();
  try {
  service.linkToDeath(deathRecipient, 0);
  } catch (RemoteException e) {
  e.printStackTrace();
  }
 }

 @Override
 public void onServiceDisconnected(ComponentName name) {
  Log.i("MainActivity.conn","@@ onServiceDisconnected name="+name);
 }
 };
 IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {//注册一个死亡代理,监测连接状态
 @Override
 public void binderDied() {
  Log.i("MainActivity","@@ binderDied "+(orderManager==null));
  if(orderManager==null){
  return;
  }
  orderManager.asBinder().unlinkToDeath(deathRecipient, 0);
  orderManager = null;
  //重新绑定
  bindOrderService();
 }
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 Log.i("MainActivity","@@ onCreate");
 setContentView(R.layout.activity_main);
 getLayoutInflater();
 //view
 search_button=findViewById(R.id.search_button);
 add_button=findViewById(R.id.add_button);
 recyclerView=findViewById(R.id.recyclerView);
 //组装recyclerView
 LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
 linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
 recyclerView.setLayoutManager(linearLayoutManager);
 adapter=new OrderAdapter(this);
 recyclerView.setAdapter(adapter);
 //onclick
 search_button.setOnClickListener(this);
 add_button.setOnClickListener(this);
 //bind
 bindOrderService();
 }
 private void bindOrderService(){
 Intent intent = new Intent("com.example.wang.ordermanager.OrderService");
 intent.setPackage("com.example.wang.ordermanager");
 intent.addCategory(Intent.CATEGORY_LAUNCHER);
 bindService(intent, conn, Context.BIND_AUTO_CREATE);
 }
 /**
 * 重新获取数据并刷新列表。
 */
 private void refreshOrderList(){
 try {
  if(orderManager!=null){
  orderList = orderManager.getAll();
  }
  if(orderList!=null){
  adapter.setData(orderList);
  adapter.notifyDataSetChanged();
  }
 } catch (RemoteException e) {
  e.printStackTrace();
 }
 }

 @Override
 public void onClick(View v) {
 if(v==search_button){
  //刷新订单
  refreshOrderList();
 }else if(v==add_button){
  //增加订单
  try {
  OrderBean orderBean=new OrderBean();
  Random random=new Random();
  orderBean.setAmount(random.nextInt(800)+100);
  orderBean.setId(random.nextInt(100000000)+100000+"");
  orderBean.setName("玩具"+random.nextInt());
  orderManager.add(orderBean);
  refreshOrderList();
  } catch (RemoteException e) {
  e.printStackTrace();
  }
 }
 }

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

4、编写服务端代码

这里主要做两件事,第一个是移植aidl文件和bean类,将client中的aidl文件和OrderBean移植过来,文件路径要保持一致,第二个是编写OrderService.java类。

//OrderService.java
package com.example.wang.ordermanager;
...

public class OrderService extends Service{
 private CopyOnWriteArrayList<OrderBean> list = new CopyOnWriteArrayList<>();

 @Override
 public void onCreate() {
 super.onCreate();
 Log.i("OrderService","@@ onCreate");

 }

 @Nullable
 @Override
 public IBinder onBind(Intent intent) {
 Log.i("OrderService","@@ onBind");
 return binder;
 }

 Binder binder = new IOrderManager.Stub(){

 @Override
 public List<OrderBean> getAll() throws RemoteException {
  return list;
 }

 @Override
 public void add(OrderBean bean) throws RemoteException {
  list.add(bean);
 }
 };

}


OrderService服务在AndroidManifest.xml中的配置如下:

<service android:name=".OrderService"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
  <action android:name="com.example.wang.ordermanager.OrderService"/>
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
 </service>

代码编写就完成了,运行时需要先运行服务端app,再运行client,如果运行过程中OrderService服务断掉了,client会通过死亡代理得到通知,再重新绑定即可。

运行如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Android通过AIDL在两个APP之间Service通信,包括了Android通过AIDL在两个APP之间Service通信的使用技巧和注意事项,需要的朋友参考一下 一、项目介绍 【知识准备】   ①Android Interface definition language(aidl,android接口定义语言),其目的实现跨进程的调用。进程是程序在os中执行的载体,一个程序对应

  • 本文向大家介绍Android 进程间通信AIDL使用详解,包括了Android 进程间通信AIDL使用详解的使用技巧和注意事项,需要的朋友参考一下 一、概述 AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码。从某种意义上说AIDL其实是一

  • 本文向大家介绍Android多进程间采用AIDL方式进行通信,包括了Android多进程间采用AIDL方式进行通信的使用技巧和注意事项,需要的朋友参考一下 在上一节中,我介绍了Android中Service的生命周期以及一些有关知识。在这一节中,我采用代码编写的方式来介绍一下不同程序之间也就是不同进程之间通信采用AIDL方式。 首先我需要解释一下,不同程序进程间采用AIDL方式启动服务,我们可以看

  • 本文向大家介绍Android AIDL实现与服务相互调用方式,包括了Android AIDL实现与服务相互调用方式的使用技巧和注意事项,需要的朋友参考一下 通过AIDL接口在进程间传递数据,记录在开发中遇到的一写问题 AIDL支持数据类型如下: 1. Java 的原生类型 2. String 和CharSequence 3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的

  • 问题内容: 我的机器在窗口7上运行。我想 在同一机器上运行的两个android仿真器之间进行通信。 仿真器第一个正在侦听某些IP 10.0.2.15,第二个仿真器尝试 创建IP 它给出了异常,无法连接到10.0.2.15,有人知道如何 解决此问题吗? 编辑:我已经读过 https://developer.android.com/studio/run/emulator-networking#conn

  • 本文向大家介绍浅谈Android Aidl 通讯机制,包括了浅谈Android Aidl 通讯机制的使用技巧和注意事项,需要的朋友参考一下 服务端: 首先是编写一个aidl文件,注意AIDL只支持方法,不能定义静态成员,并且方法也不能有类似public等的修饰符;AIDL运行方法有任何类型的参数和返回值,在java的类型中,以下的类型使用时不需要导入包(import),基本数据类型、String、

  • 它现在是如何工作的: 微服务X用静态ip向微服务Y发出REST API请求 我试图通过在docker-compose中创建一个已使用的定义网络来实现这一点: 例如,我可以从容器X ping到容器Y,但不能Curl。我该如何解决这个问题,或者这不是实现我想要的最好的方法。

  • 本文向大家介绍Android  AIDL——进程通信机制详解,包括了Android  AIDL——进程通信机制详解的使用技巧和注意事项,需要的朋友参考一下 Android  AIDL, Android进程机制通信机制,这里就整理下AIDL 的知识,帮助大家学习理解此部分知识! 什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口