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方式实现播放音乐案例
  • Android AIDL实现两个APP间的跨进程通信实例
  • Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
  • 使用Android studio创建的AIDL编译时找不到自定义类的解决办法
  • Android 使用【AIDL】调用外部服务的解决方法
  • 基于Android AIDL进程间通信接口使用介绍
  • Android程序设计之AIDL实例详解
  • 实例讲解Android中的AIDL内部进程通信接口使用
  • Android Studio创建AIDL文件并实现进程间通讯实例
  • Android多进程间采用AIDL方式进行通信
(0)

相关推荐

  • Android AIDL实现两个APP间的跨进程通信实例

    本文为大家分享了Android AIDL实现两个APP间的跨进程通信实例,供大家参考,具体内容如下 1 Service端创建 首先需要创建一个Android工程然后创建AIDL文件,创建AIDL文件主要为了生成继承了Binder的Stub类,以便应用Binder进行进程间通信 servier端结构如下 AIDL代码如下 // IBookManager.aidl package com.example.bookserver.aidl; // Declare any non-default type

  • 基于Android AIDL进程间通信接口使用介绍

    AIDL:Android Interface Definition Language,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口. ICP:Interprocess Communication ,内部进程通信. 使用: 1.先创建一个aidl文件,aidl文件的定义和java代码类似,但是!它可以引用其它aidl文件中定义的接口和类,但是不能引用自定义的java类文件中定义的接口和类,要引用自定义的接口或类,需要为此类也定义一个对应的aidl文件,并且此

  • Android应用程序四大组件之使用AIDL如何实现跨进程调用Service

    一.问题描述 Android应用程序的四大组件中Activity.BroadcastReceiver.ContentProvider.Service都可以进行跨进程.在上一篇我们通过ContentProvider实现了不同应用之间的跨进程调用,但ContentProvider主要是提供数据的共享(如sqlite数据库),那么我们希望跨进程调用服务(Service)呢?Android系统采用了远程过程调用(RPC)方式来实现.与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言

  • 实例讲解Android中的AIDL内部进程通信接口使用

    首先描述下我们想要实现的内容,我们希望在一个应用中通过点击按钮,去操作另一个进程中应用的音乐播放功能. 如图,我们点击"播放"时,系统就会去远程调用我们提供的一个service(与当前service不是同一个应用哦),然后操作service中的音乐播放,点击"停止"则会终止播放.想要重新播放的话,必须先点"销毁service",再点播放按钮哦.(至于这里为什么要先点销毁按钮才能播放,完全是为了给大家展示下,远程调用service时,怎么去解绑se

  • Android 使用【AIDL】调用外部服务的解决方法

    在Android 中有一种服务说是服务其实倒不如说是一个接口,这个接口名为:Android Interface Definition Language ,这个接口可提供跨进程访问服务,英文缩写为:AIDL. 此种服务的好处在于,多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作,下面将通过一个DEMO 演示AIDL 是如何为应用程序之间提供服务的.本文大纲为:•1.创建AIDL 服务端.•2.创建AIDL 客户端.•3.客户端调用服务端提供的服务接口.

  • Android Studio创建AIDL文件并实现进程间通讯实例

    在Android系统中,跨进程通信是非常普遍的事情,它用到了Binder机制处理进程之间的交互.Binder机制会开放一些接口给Java层,供android开发工程师调用进程之间通信.这些接口android封装到了AIDL文件里,当我们项目用到跨进程通信时可以创建.aidl文件,.aidl文件可以协助我们达到跨进程的通信.下面简单介绍用AndroidStudio创建AIDL文件的过程. a.新建AIDL文件 1.项目文件夹右键---> new --->选择AIDL 2.自定义一个接口名称 3.

  • Android程序设计之AIDL实例详解

    通常来说,AIDL这项技术在我们的应用开发过程中并不是很常用,虽然新浪微博提供了SSO登录,但是其原理就是使用AIDL.本文就以完整的实例形式讲述了AIDL的原理及实现方法. AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数,

  • Android使用AIDL方式实现播放音乐案例

    本文实例为大家分享了Android使用AIDL方式实现播放音乐的具体代码,供大家参考,具体内容如下 思路: ① 新建两个APP项目或者Module,一个作为服务端,一个作为客户端,在服务端创建service ② 在两个module的main文件中分别新建两个aidl文件(接口),里边定义处理音乐的方法 ③ 在两个AIDL文件定义过方法后在任务栏给他们makeproject,编译成Java文件,才能在service和acvitity中使用 interface.Stub需要实例化,实现远程方法 ④.

  • Android多进程间采用AIDL方式进行通信

    在上一节中,我介绍了Android中Service的生命周期以及一些有关知识.在这一节中,我采用代码编写的方式来介绍一下不同程序之间也就是不同进程之间通信采用AIDL方式. 首先我需要解释一下,不同程序进程间采用AIDL方式启动服务,我们可以看作成client客户端与server服务端之间的通信,无非c/s都是安装在了我们的智能手机设备Android系统之上.好了,理解到这里我们就可以继续往下介绍了. 首先我们编写server服务端程序: 1)我们新建一个应用程序S,它的应用程序架构如下: 2)

  • 使用Android studio创建的AIDL编译时找不到自定义类的解决办法

    使用AS创建ADIL文件时AS会在main文件夹下给我们生成一个aidl文件夹和一个相同包名的包,通常我们会把所有和ADIL相关的类或文件放在这个包下,但是如果存在自定义的类时,程序编译时无法通过,提示找不到自定义的包.解决办法如下,在启动Module的build.gradle中加入如下代码: sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java', '

随机推荐