美文网首页
AndroidIPC跨进程通讯AIDL(二)

AndroidIPC跨进程通讯AIDL(二)

作者: 没有了遇见 | 来源:发表于2023-07-29 14:02 被阅读0次

    android系统进程隔离内存隔离,进程间不能共享内存 所以就需要一些机制在不同进程间进行数据通讯

    AIDL:Android Interface Definition Language 安卓接口定义语言,封装了Binder实现内存通讯.

    Android AIDL实现

    1:创建服务端

    1.1创建AIDL
    包名右键-->New--->AIDL--->AIDLFile
    1.1
    IShareDataInterface.aidl

    // IShareDataInterface.aidl
    package com.wu.ipcservice;
    
    import com.wu.ipcservice.IShareDataListener;
    import com.wu.ipcservice.ShareDataInfo;
    
    interface IShareDataInterface {
    
    
        void sendShareData(int key, String values);
    
        String getShareData(int key) ;
    
        void registerCallback(int id, IShareDataListener callback) ;
    
        void unregisterCallback(IShareDataListener callback) ;
    
        void sendShareDataInfo(in ShareDataInfo info);
    
    }
    
    

    1.2创建封装数据类型:注意实现parcelable 序列化

    1.2.1 创建封装数据

    package com.wu.ipcservice;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    /**
     * 作者:吴奎庆
     * <p>
     * 时间:7/29/23
     * <p>
     * 用途:
     */
    
    
    public class ShareDataInfo implements Parcelable {
        int type;
        String content;
    
    
        protected ShareDataInfo(Parcel in) {
            type = in.readInt();
            content = in.readString();
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(type);
            dest.writeString(content);
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        public static final Creator<ShareDataInfo> CREATOR = new Creator<ShareDataInfo>() {
            @Override
            public ShareDataInfo createFromParcel(Parcel in) {
                return new ShareDataInfo(in);
            }
    
            @Override
            public ShareDataInfo[] newArray(int size) {
                return new ShareDataInfo[size];
            }
        };
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
    
        @Override
        public String toString() {
            return "ShareDataInfo{" +
                    "type=" + type +
                    ", content='" + content + '\'' +
                    '}';
        }
    }
    
    
    

    1.1.3 创建封装数据的AIDL文件(只需要一个parcelable ShareDataInfo)

    package com.wu.ipcservice;
    parcelable ShareDataInfo;
    

    注意

    • 千万注意Make project一下(小锤子)
    • 注意导包
    • 注意序列化


      service.png
    1. 创建服务
      2.1创建服务Binder ShareDataBinder.
    package com.wu.ipcservice;
    
    import android.os.RemoteException;
    import android.util.Log;
    
    /**
     * 作者:吴奎庆
     * <p>
     * 时间:7/29/23
     * <p>
     * 用途:
     */
    
    
    public class ShareDataBinder extends IShareDataInterface.Stub {
    
        IShareDataListener callback;
    
        @Override
        public void sendShareData(int key, String values) throws RemoteException {
            Log.e("IPCService:", "收到了客户端的消息:" + values);
            if (callback != null)
                callback.notifyShareData(key, values);
        }
    
        @Override
        public String getShareData(int key) throws RemoteException {
            return "返回服务了服务层数据";
        }
    
        @Override
        public void registerCallback(int id, IShareDataListener callback) throws RemoteException {
            this.callback = callback;
        }
    
        @Override
        public void unregisterCallback(IShareDataListener callback) throws RemoteException {
            callback = null;
        }
    
        @Override
        public void sendShareDataInfo(ShareDataInfo info) throws RemoteException {
            Log.e("IPCService:", "收到了客户端的ShareDataInfo消息:" + info.toString());
        }
    }
    
    

    2.2 创建ShareDataService服务

    package com.wu.ipcservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    import androidx.annotation.Nullable;
    
    /**
     * 作者:吴奎庆
     * <p>
     * 时间:7/29/23
     * <p>
     * 用途:
     */
    
    
    public class ShareDataService extends Service {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ShareDataBinder();
        }
    }
    
    

    2.3 清单配置
    process:进程名
    exported: 可外部访问
    action: 外部开启的Action

     <service
               android:name=".ShareDataService"
               android:process=":ipc_service"
               android:exported="true" >
               <intent-filter>
                   <action android:name="com.wu.ipc.service" />
               </intent-filter>
           </service>
    

    2.创建客户端访问数据

    2.1 将服务端创建的AIDL文件复制都客户端同样的位置线

    • 位置:src-->main 下(和java统一目录下)
    • make project (小锤子)一下
    • 将创建的封装数据类型 放到和服务端同样的包名下(创建服务端包名,然后复制封装对象即可)
    client.png

    2.4 跨进程通讯

    package com.wu.ipcclient;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    import com.wu.ipcservice.IShareDataInterface;
    import com.wu.ipcservice.ShareDataInfo;
    
    public class MainActivity extends AppCompatActivity {
        private IShareDataInterface shareDataInterface;
        boolean isConnected;
        ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                isConnected = true;
                shareDataInterface = IShareDataInterface.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                isConnected = false;
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            findViewById(R.id.bt_connected).setOnClickListener(v ->{
                startService();
            });
    
            findViewById(R.id.bt_send).setOnClickListener(v ->{
                try {
                    shareDataInterface.sendShareData(10086,"发送了消息");
                    Log.e("IPCClient:","发送了消息:"+10086);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            });
            findViewById(R.id.bt_get).setOnClickListener(v ->{
                try {
                    String content=shareDataInterface.getShareData(10086);
                    Log.e("IPCClient:","获取消息:"+content);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            });
            findViewById(R.id.bt_get_info).setOnClickListener(v ->{
                try {
                    ShareDataInfo info= new ShareDataInfo(10010,"对象信息");
                    shareDataInterface.sendShareDataInfo(info);
    
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            });
        }
    
        private void startService() {
    
            ComponentName name = new ComponentName("com.wu.ipcservice", "com.wu.ipcservice.ShareDataService");
            Intent intent = new Intent();
            intent.setAction("com.wu.ipc.service");
            intent.setComponent(name);
            this.bindService(intent, this.mServiceConnection, this.BIND_AUTO_CREATE);
    
        }
    }
    
    

    注意

    • 注意引用不到的时候make project 一下
    • 注意导包(封装数据类型注意序列化)
    • 注意清单文件配置
    • 注意 bindService()

    总结

    AIDL是通过IBinder封装的通讯协议来实现IPC的,AIDL是通过AIDL类的内部类Stub继承了IBinder的子类Binder实现跨进程通讯的Binder自身也是可以做跨进程通讯的.
    核心方法:

    • onTransact(int code, Parcel data, Parcel reply, int flags) 响应数据
    • transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
      int flags) 发送

    服务端源码

    客户端源码

    相关文章

      网友评论

          本文标题:AndroidIPC跨进程通讯AIDL(二)

          本文链接:https://www.haomeiwen.com/subject/qxjdpdtx.html