安卓进程间通信AIDL

95 篇文章 0 订阅

今天介绍下安卓跨进程同时AIDL基本使用和需要注意的地方,我以登录为例,

新建个项目MyAidl,新建一个IMyAidlInterface 的AIDL接口,

 

在interface Nmae输入接口名称

 

//再在aidl文件夹下新建一个Bean对象,(注意自定义bean对象,需要现在aidl新建编译,再建Java类bean,要不你在aidl会报类名冲突

Bean.adil代码如下

// Bean.aidl
package cn.zdh.myaidl;

// Declare any non-default types here with import statements
//导入对应的Bean对象
parcelable Bean;

再在Java文件夹新建个Bean对象代码如下(注意自定义bean类需要实现parcelable,如果aidl接口使用out 或者inout需要写readFromParcel(Parcel reply)方法; 注意Java的bean类的包名必须和aidl的包名一致

public class Bean implements Parcelable {

    private String name;

    private String password;

    public Bean() {
    }

    public Bean(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeString(this.password);
    }


    protected Bean(Parcel in) {
        this.name = in.readString();
        this.password = in.readString();
    }

    public static final Parcelable.Creator<Bean> CREATOR = new Parcelable.Creator<Bean>() {
        @Override
        public Bean createFromParcel(Parcel source) {
            return new Bean(source);
        }

        @Override
        public Bean[] newArray(int size) {
            return new Bean[size];
        }
    };


    /**
     * adil 使用out 或者inout 需要写这个方法
     */

    public void readFromParcel(Parcel reply) {
        this.name = reply.readString();
        this.password = reply.readString();

    }
}

 

//下面写aidl接口

//使用AIDL需要注意下面几点

//1:同包也要导包
//2: 支持基础类型数据传递,自定义类需要实现parcelable序列化
//3:自定义的类名和包名必须和 AIDL的类名包名一致
//4:in 服务端 不能修改客服端的入参数数据(bean),但是可以获取参数数据
//5:out 服务端 能修改客服端的入参数据(bean),但是并不可以获取参数数据
//6:inout 服务 能修改客服端的入参数据(bean),也可以获取参数数据 ,但是消耗性能最大
//7:注意 使用out inout Java的bean对象需要写 readFromParcel(Parcel reply){}方法,在方法里面把字段读取出来

import cn.zdh.myaidl.Bean;

interface IMyAidlInterface {

void login(in Bean bean);


}

 

 

//Java对应service代码

/**
 * 实现aidl接口方法
 */
public class AidlService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }


    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show();
            }

        }
    };


    /**
     * 获取aidl的binder对象
     * 注意在子线程
     */
    private IBinder iBinder = new IMyAidlInterface.Stub() {
        @Override
        public void login(Bean bean) throws RemoteException {
            //判断用户账户是的正确
            String name = bean.getName();
            String password = bean.getPassword();
            Message message = handler.obtainMessage();
            if (name.equals("张三") && password.equals("123456")) {
                message.what = 1;
                handler.sendMessage(message);
            } else {
                Log.e("zdh", "------" + Thread.currentThread().getName());
                message.what = 0;
                handler.sendMessage(message);
            }


        }
    };
}

 

 

//创建一个activity测试登录,代码如下,(注意 在mainfest添加process 新建个进程)

public class TextActivity extends AppCompatActivity {

    private IMyAidlInterface iMyAidlInterface;
    private ServiceConnection conn;
    private EditText etName, etPassword;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text);
        etName = findViewById(R.id.et_name);
        etPassword = findViewById(R.id.et_password);


        //bindService启动服务
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("cn.zdh.myaidl", "cn.zdh.myaidl.AidlService"));
        conn = new MyServiceConnection();
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解除服务绑定
        unbindService(conn);
    }

    //登录
    public void load(View view) {
        Bean bean = new Bean();
        bean.setName(etName.getText().toString());
        bean.setPassword(etPassword.getText().toString());
        try {
            //添加数据
            iMyAidlInterface.login(bean);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private class MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //获取aidl接口对象
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

}

 

  //mainfest代码

//注意 process 需要使用双引号 :
<activity android:name=".TextActivity"  android:process=":t"/>
//不要忘记注册服务        
<service android:name=".AidlService" />

代码运行效果如下

 

总结:使用aidl需要注意的

//1:同包也要导包
//2: 支持基础类型数据传递,自定义类需要实现parcelable序列化
//3:自定义的类名和包名必须和 AIDL的类名包名一致
//4:in 服务端 不能修改客服端的入参数数据(bean),但是可以获取参数数据
//5:out 服务端 能修改客服端的入参数据(bean),但是并不可以获取参数数据
//6:inout 服务 能修改客服端的入参数据(bean),也可以获取参数数据 ,但是消耗性能最大
//7:注意 使用out inout Java的bean对象需要写 readFromParcel(Parcel reply){}方法,在方法里面把字段读取出来
//8:Java是service 是在子线程

 

源码地址 https://github.com/zhudaihao/MyAIDL

 

注意如果服务端和客户端是两个项目,需要在注册的service添加

android:exported="true",
<service android:name=".ViewAidlService"
    android:exported="true">
</service>

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值