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会通过死亡代理得到通知,再重新绑定即可。
运行如下:
这里写图片描述

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页