美文网首页
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