• Android AIDL 进行进程间通讯(IPC)


    编写AIDL文件时,需要注意:

    1.接口名和aidl文件名相同。

    2.接口和方法前不用加访问权限修饰符 (public、private、protected等,也不能用final、static)。

    3.AIDL默认支持的类型包括java基本类型 (int、long、boolean等) 和 (String、List、Map、CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是AIDL支持的类型,如果使用自定义类型作为参数或者返回值,自定义类型必须实现Parcelable接口。

    4.自定义类型和AIDL生成的其它接口类型,在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。

    5.在aidl文件中所有非java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。

    6.Java原始类型默认的标记为in,不能为其它标记。

    StudentQuery-aidl文件:(通讯双方共有)

    //因为是接口描述,所以跟接口类似,AIDL
    interface StudentQuery{
    
        String queryStudent(int number); // 根据id查询学生名称
    }

    远程服务端:( 为远程服务隐式在清单文件中添加action :com.sample.student.query)

     1 public  class StudentQueryService extends Service {
     2 
     3       private String[] names = {"张三", "李四" ,"赵武"};
     4       private IBinder binder = new StudentQueryBinder();
     5  
     6       @Overrider
     7       public IBinder onBind (Intent intent) {
     8             return binder;
     9       }
    10 
    11       private final class StudentQueryBinder extends StudentQuery.Stub {
    12 
    13                 public String queryStudent(int number) throws RemoteException {
    14                          return query(number);
    15                 }
    16       }
    17 
    18       private String query (int number) {
    19 
    20               if (number > 0 && number < 4) {
    21                       return names[number - 1];
    22               }
    23               return "没有该学生编号";
    24       }
    25 }

    客户端(Activity):

     1 public class MainActivity extends Activity {
     2 
     3        private StudentQuery studentQuery;
     4        private StudentConnection conn = new StudentConnection();
     5        
     6        @Override
     7        public void onCreate(Bundle savedInstanceState) {
     8             super.onCreate(savedInstanceState);
     9             setContentView (R.layout.main);
    10             
    11             Intent service = new Intent ("com.sample.student.query");
    12             bindService (service, conn, BIND_AUTO_CREATE);
    13        }
    14 
    15        // 点击查询
    16        public void queryStudent(View view) {
    try {
    17 studentQuery.queryStudent(0);
    } catch (RemoteException e) {
    e.printStackTrace();
    }
    18 } 19 20 private final class StudentConnection implements ServiceConnection { 21 22 public void onServiceConnected (ComponentName name, IBinder service) { 23 // asInterface转换代理对象为接口类型。 24 studentQuery = StudentQuery.Stub.asInterface(service); 25 } 26 27 public void onServiceDisconnected (ComponentName name) { 28 studentQuery = null; 29 } 30 } 31 32 @Override 33 protected void onDestroy() { 34 // 销毁 35 unbindService(conn); 36 super.onDestroy(); 37 } 38 }

    进程间传递自定义类型参数:

    1)自定义类型必须实现Parcelable接口,并且实现Parcelable接口的writeToParcel方法:

    1 public void writeToParcel (Parcel dest, int flags)

    2)自定义类型中必须含有一个名称为CREATOR的静态成员,该成员对象要求实现Parcelable.Createor接口及其方法。

    3)创建一个aidl文件声明你的自定义类型。

    Parcelable接口的作用:

    实现了Parcelable接口的实例可以将自身的状态信息(状态信息通常指的是各成员变量的值)写入Parcel,也可以从Parcel中恢复其状态,Parcel用来完成数据的序列化传递。

    AIDL通讯方式:

    在Java中不支持跨进程内存共享的。在JavaEE中,采用RMI通过序列化传递对象。

    AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通讯(IPC),AIDL的IPC机制和EJB所采用的CORBA很类似,进程间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成响应的对象,由于进程之间的通信信息学需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成。

  • 相关阅读:
    连续时间单位冲激信号δ(t)的基本性质
    数据结构练习
    数据结构练习
    数据结构练习
    使用 matplotlib 绘制带日期的坐标轴
    数据结构练习
    c++ primer 练习10.33_p363
    C++迭代器之'插入迭代器
    C++ 11 Lambda表达式
    《C++ Primer》读书笔记—第十章 泛型算法
  • 原文地址:https://www.cnblogs.com/CharlesGrant/p/4873191.html
Copyright © 2020-2023  润新知