一聚教程网:一个值得你收藏的教程网站

热门教程

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

时间:2022-06-25 23:01:29 编辑:袖梨 来源:一聚教程网

今天开发了一个功能,通过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 CREATOR = new Creator() {
 @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 getAll();
 void add(in OrderBean bean);
}

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

#activity_main.xml - 主页面布局


 
 
 

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

//MainActivity.java
package com.example.wang.client;
...
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
 private List 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 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 getAll() throws RemoteException {
  return list;
 }

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

}


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


  
  
  
  
 

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

运行如下:

热门栏目