美文网首页
android AIDL

android AIDL

作者: DouMarK | 来源:发表于2019-07-26 00:50 被阅读0次

    进程通讯AIDL,即Android Interface Definition Language(安卓接口定义语言),主要是用来跨进程访问,例如服务器端与客户端通信时,服务端与客户端如何收发数据需要通过一个规范,一个接口等

    语法:

    • AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。但是在使用其他AIDL生成的接口时候,除了java的八种基本类型外,其他都需要import这些接口。
    • AIDL只支持接口方法,不能公开static变量。
    • 接口和方法前面不要加访问权限修饰符:public ,private,protected等,也不能用static final
    • 自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义 的包在同一个包中。

    代码实例:

    service

    首先src内创建一个AIDL,并在interface内写好需要给客户端调用的方法:

    interface IMyService{
      void getValue();
    }
    

    新建的AIDL文件内的接口有一个初始化化的方法,可以删除掉,接着clean一下项目,make project后as会自动生成一个java文件,里面是一些接口信息。
    然后创建一个继承service的类,并继承IMyservice接口,重写在Aidl内创建的方法:

    public class MyService extends Service {
    
        @Override
        public IBinder onBind(Intent arg0) {
            return new MyServiceImpl();
        }
    
        public class MyServiceImpl extends IMyService.Stub {
            @Override
            public void getValue() throws RemoteException {
                Log.w("Aidl Test", "创建成功");
            }
    }
    

    AndroidMainfest.xml内声明service名字:

    <service android:name=".MyService">
          <intent-filter>
              <action android:name="com.study.Service"/>
          </intent-filter>
    </service>
    

    client

    然后创建一个client工程,把service工程生成的AIDL文件包括aidl目录都复制到client工程的src目录内(client重复clean,make project一次)。
    接着Main绑定service,接着就可以调用服务器生成的getValue()方法了.

    public class AidlClientTestActivity extends AppCompatActivity implements View.OnClickListener {
        IMyService  mIMyService;
        private ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                     mIMyService =  IMyService.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_aidl_client_test);
    
            Intent serviceIntern = new Intent();
            //Service name
            serviceIntern.setAction("com.study.Service");
            //Package name        
            serviceIntern.setPackage("com.study.service");
            bindService(serviceIntern, mConnection, Context.BIND_AUTO_CREATE);
            Button aidlTest = findViewById(R.id.test);
            aidlTest.setOnClickListener(this);
         }
    
        @Override
        public void onClick(View v) {
          witch (v.getId()) {
                case R.id.test:
                    try {
                      mIMyService.getValue();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                  break;
        }
    }
    

    接着编译service后,运行客户端,点击按钮就可以看到service,显示的log了
    但是aidl不支持Object类型,Object类型在很多地方都能用到,这时候怎么办呢?
    使用Parcelable(Parcelable是Android为我们提供的序列化的接口)即可

    aidl传递对象

    建立一个javabean并实现parcelable 接口:

    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Events implements Parcelable {
    
        String name;
    
        public Events(String name) {
            this.name = name;
        }
    
        public Events() {
    
        }
    
        public static final Creator<Event> CREATOR = new Creator<Event>() {
            @Override
            public Events createFromParcel(Parcel in) {
                return new Events(in);
            }
    
            @Override
            public Events[] newArray(int size) {
                return new Events[size];
            }
        };
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        protected Events(Parcel in) {
            name = in.readString();
        }
    
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
        }
    }
    
    

    创建一个和javabens一样名字的AIDL,并声明其类型和所在的包,这种aidl在编译后不会自动生成一个java文件,因为我刚刚开始说过,aidl在除了几种基本类型外,其他类型传递需要import,所以javabens的aidl只是作声明对应类所在的位置和类型

    // Events.aidl
    package com.study.service;
    
    // Declare any non-default types here with import statements
    parcelable Events;
    

    接着一样在IMyservice.aidl内声明会调用的方法,并import Events 所在的目录位置:

    import com.study.service.Events;
    
    interface IMyService {
         void getValue();
         void printEvents(in Events events);
     }
    

    接着clean一下工程,并在Myservic类重写该方法:

    
    public class MyService extends Service {
    
        @Override
        public IBinder onBind(Intent arg0) {
            return new MyServiceImpl();
        }
        public class MyServiceImpl extends IMyService.Stub {
            @Override
            public void getValue() throws RemoteException {
                Log.w("Aidl Test", "building successful");
            }
    
            @Override
            public void printEvents(Events events) throws RemoteException {
                Log.w("Events call successful ", events.getName());
            }
        }
    }
    

    把aidl重新复制在client工程,并在client工程内建立一个目录与Events类所在的包一样,并把events类复制过去。clean 一下project,调用方法:

    public class AidlClientTestActivity extends AppCompatActivity implements View.OnClickListener {
        IMyService  mIMyService;
        private ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                     mIMyService =  IMyService.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_aidl_client_test);
    
            Intent serviceIntern = new Intent();
            //Service name
            serviceIntern.setAction("com.study.Service");
            //Package name        
            serviceIntern.setPackage("com.study.service");
            bindService(serviceIntern, mConnection, Context.BIND_AUTO_CREATE);
    
            Button aidlTest = findViewById(R.id.test);
            aidlTest.setOnClickListener(this);
            Button addEvents = findViewById(R.id.events);
            addDevice.setOnClickListener(this);
         }
    
        @Override
        public void onClick(View v) {
          witch (v.getId()) {
                case R.id.test:
                    try {
                      mIMyService.getValue();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                case R.id.events:
                   try {
                      Events events = new Events();
                      events.setName("study");
                      mIMyService.printEvents(events);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                default:
                  break;
        }
    }
    

    重新运行一下service,和client就可以看到log了。

    相关文章

      网友评论

          本文标题:android AIDL

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