美文网首页
android studio下AIDL 使用

android studio下AIDL 使用

作者: 有点健忘 | 来源:发表于2019-02-18 15:04 被阅读23次

参考
https://www.cnblogs.com/chase1/p/7135961.html
https://developer.android.com/guide/components/aidl

  1. 服务端添加aidl文件
    如下图所示,在src目录上,右键new一个aidl文件,写上aidl文件的名字,就自动生成了
image.png

结构如下


image.png

生成的aidl文件如下,接口里的方法改成自己实际需要的即可

package com.charliesong.demo0327;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
     String getPid();
     void changeState(int state);
     int getState();
}

然后在下图所示的地方可以看到自动生成的同名java文件,如果没有生成,或者你修改了aidl接口文件的方法,那么点下build》make project也可以生成对应的java文件的。


image.png
  1. 写个service
    主要就是实例化一个binder,也就是我们上边定义的aidl接口的对象,如下,然后onBind方法里返回即可。
class ServiceNothing:Service(){
    override fun onBind(intent: Intent?): IBinder? {
        println("ServiceNothing on bind================")
        return binder
    }

    var stateOld=-1
    private val binder=object :IMyAidlInterface.Stub(){
        override fun getPid(): String {

            return packageName
        }

        override fun changeState(state: Int) {
            stateOld=state
        }

        override fun getState(): Int {
          return  stateOld
        }
    }
}
  1. 注册服务
    intent-filter 是用来在别的app启动这个服务用的
        <service android:name=".a1.ServiceNothing" >
            <intent-filter>
             <action android:name="com.xx.xxx"/>
              </intent-filter>
        </service>
  1. 复制服务端的aidl目录的文件到客户端
    就是main目录下那个aidl目录,复制到需要的工程main目录下,然后make project 。
    使用就比较简单了,如下bind服务
        Intent intent=new Intent("com.xx.xxx");
        intent.setPackage("com.charliesong.demo0327");
        bindService(intent,conn,Context.BIND_AUTO_CREATE);

conn如下

 IMyAidlInterface aidlInterface;
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            aidlInterface=IMyAidlInterface.Stub.asInterface(service);
          //拿到aidlInterface 就可以调用它里边的方法拉。
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            aidlInterface=null;
        }
    };

上边简单的就完事了。

自定义类

image.png

首先我们可以看到用android studio 右键生成的aidl目录和我们的java目录不在一起的,在这个aidl目录下,添加aidl文件是没啥问题的,系统会自动识别的,如果添加java类,系统是不识别的。
所以我们自定义类有两种办法:
一种,你把要自定义的类写在java目录下,
另一种,就写在aidl目录下,不过需要在build.gradle文件下添加如下代码

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.charliesong.demo0327"
        minSdkVersion 18
//省略
    }

//需要添加下边的代码,主要是把aidl目录添加到java目录下
    sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }

我们这里采专用第二种

  1. 首先自定义一个类,实现Parcelable接口
public class OurPacket2 implements Parcelable 

然后添加同名的aidl文件,只需要两行代码,一个是package,一个parcelable 后边跟着类的名字

// OurPacket2.aidl
package com.charliesong.demo0327;

// Declare any non-default types here with import statements
parcelable OurPacket2;
  1. 之后aidl文件里就可以用这个自定义的类了,如下
    注意:import必须添加,方法的参数前边必须添加 in ,out 或者inout
    关于这3种tag的介绍可以看这里https://blog.csdn.net/luoyanglizi/article/details/51958091
package com.charliesong.demo0327;
import com.charliesong.demo0327.OurPacket2;
interface IMyAidlInterface {
     String getPid();
     void setaa(inout OurPacket2 packet);
}

完事编译,完事挂了。一直提示自定义类找不到readFromParcel方法,那就给他加一个呗。完事就ok了

public class OurPacket2 implements Parcelable {

    public void readFromParcel(Parcel in){
        pid=in.readInt();
        name=in.readString();
    }
  1. 其他步骤就和普通的一样了。把adil目录复制过去即可,记得客户端也添加这个,这样方便,aidl相关的 都在一个目录下。
    sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }

自定义数据数据流向in,out,inout

上边有链接,有详细的介绍,可以去看看,下边只说结论
如下,增加3个方法测试

     void addPacketIn(in OurPacket2 packet);
     void addPacketOut(out OurPacket2 packet);
     void addPacketInOut(inout OurPacket2 packet);

然后服务端的实现如下,就是打印下接收点到的值,并且修改name值

    private val binder=object :IMyAidlInterface.Stub(){
        override fun addPacketIn(packet: OurPacket2) {
            println("addPacket in....${packet}")
            packet.name="in"
        }

        override fun addPacketOut(packet: OurPacket2) {
            println("addPacket out....${packet}")
            packet.name="out"
        }

        override fun addPacketInOut(packet: OurPacket2) {
            println("addPacket inout....${packet}")
            packet.name="in out"
        }

客户端也一样,打印,里边有打印的日志

        public void onServiceConnected(ComponentName name, IBinder service) {

            aidlInterface=IMyAidlInterface.Stub.asInterface(service);
            try {

            OurPacket2 packet2=new OurPacket2(111,"aaaa");
            aidlInterface.addPacketIn(packet2);
            System.out.println("client1=========="+packet2);

            OurPacket2 packet22=new OurPacket2(111,"aaaa");
            aidlInterface.addPacketOut(packet22);
            System.out.println("client2=========="+packet22);

            OurPacket2 packet222=new OurPacket2(111,"aaaa");
            aidlInterface.addPacketInOut(packet222);
            System.out.println("client3=========="+packet222);

                //addPacket in....packet===pid:111 name:aaaa
                //addPacket out....packet===pid:0 name:null
                //addPacket inout....packet===pid:111 name:aaaa

                //client1==========packet===pid:111 name:aaaa
                //client2==========packet===pid:0 name:out
                //client3==========packet===pid:111 name:in out
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

in:表示数据只能从客户端到服务端,单向的,log可以看到服务端修改是无用的,name还是aaaa
out:表示数据只能从服务端传给客户端,也是单向的,log可以看到,我们通过客户端传了个有数据的packet给服务端,可服务端打印的pid==0,name是null,说明数据传不过去,相反,在服务端修改了name为out之后,客户端打印的packet的name也成了out了
inout:就是双向的,客户端可以传数据给服务端,服务端修改以后,客户端也被修改了。
简单看下自动生成的同名接口java文件
只看下in,和out,至于inout就是两者一起了。
看方法也能看到in的话,使用了参数packet
out的话没有使用参数packet,不过在方法结尾,把参数packet同步了下最后的数据

            public void addPacketIn(com.charliesong.demo0327.OurPacket2 packet) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    if ((packet != null)) {
                        _data.writeInt(1);
                        packet.writeToParcel(_data, 0);//可以看到数据packet被写到data里了
                    } else {
                        _data.writeInt(0);
                    }
                    mRemote.transact(Stub.TRANSACTION_addPacketIn, _data, _reply, 0);
                    _reply.readException();
//packet没有被修改
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

//对于out,packet参数根本就没被使用,只在最后复制了下reply数据,
            public void addPacketOut(com.charliesong.demo0327.OurPacket2 packet) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_addPacketOut, _data, _reply, 0);
                    _reply.readException();
                    if ((0 != _reply.readInt())) {
                        packet.readFromParcel(_reply);
                    }
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

暂时到这里

用的不多,都忘了,复习下,以后需要再看,如有错误,会及时修改的。

相关文章

  • Android studio 下AIDL使用

    AIDL是android app进行进程间通信的一种简单方法,本文正对在Android studio下建立AIDL...

  • android studio下AIDL 使用

    参考https://www.cnblogs.com/chase1/p/7135961.htmlhttps://de...

  • Android-AIDL使用

    AIDL使用,多进程内的多线程情况 1、在src的main目录下创建AIDL文件夹,Android studio ...

  • kotlin aidl 找不到实体类

    Book.aidl 找不到book类? Android Studio 是默认使用 Gradle 来构建 Andro...

  • Android中的AIDL

    Android中的AIDL使用详解 AIDL使用解析 Android进阶之AIDL的使用详解

  • Android AIDL与proxy,stub

    1.简单使用 利用android studio开发aidl还是非常方便的,建立一个aidl的后缀文件,在servi...

  • AIDL

    Android中AIDL的基本用法Android 中AIDL的使用与理解Android AIDL使用详解彻底明白A...

  • Android AIDL

    通过此文记录以下自己在使用AIDL时的一些理解。在Android Studio中首先定义.aidl文件: 紧接着M...

  • Android Aidl 的使用

    Android Aidl 的使用 Binder框架 -- android AIDL 的使用 Binder框架 – ...

  • Intellij IDEA 及Android Studiio下使

    Intellij IDEA / Android Studio下使用GitLab。 Android Studio基于...

网友评论

      本文标题:android studio下AIDL 使用

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