Aidl Lite

作者: 忍辞 | 来源:发表于2017-10-23 00:16 被阅读24次

由于嘴贱,立了个flag...
And thanks for this flag ...
To be continued...

Aidl

1)快速上手

  1. JavaBean
    首先,先写一个JavaBean备用
    PS:该文件不要同AIDL文件放置同一个包下,否是运行会提示找不到该类


    Book.java
  2. JavaBean.aidl
    然后在开始我们新建我们的AIDL文档前,先新建一个与上面JavaBean同名的AIDL文件,既Book.aidl,并在其中声明我们的Book对象

    Book.aidl
    并且该文件需要同上面的JavaBean文件在AIDL下放至于相同的位置,应该是IDE 解析的时候会自动去相同路径下查询,算是一种映射吧,因为待会Sync项目后source下会自动生成java代码,import引用的是aidl路径下的Book.aidl,而这则是由实现了Parcelable的Book.java映射过去的,所以这中间路径需保持一致,不然锁链就断了 (待研究)
    278511509262463_.pic_hd.jpg
  3. AIDL
    最后我们开始新建真正所要用的AIDL对象:BookManager.aidl,并在其中写入接口函数
    在我这小菜鸟现有的理解中,可以暂且将AIDL作为接口来看待,但不同于接口的是
    要注意:

    • 在AIDL文件中使用自定义的JavaBean对象(或非默认数据类型),都必须要在文件中显式地导入进来,正如注释所写的:在此用导入语句来声明任何非默认类型;
    • 并且别忘了对象参数的类型定义,既in/out/inout

    不然会导致第四步的Sync Project的时候报错......(惨痛经历)


    Aidl
  4. Sync Project with Gradle Files
    至此,在AS中点击Sync Project同步下项目,编译器将自动根据我们的AIDL文件生成同名的.java文件(若这里忘了同步,则在后续代码的调用将不会有快捷提示了)
    生成的.java路径(Project模式下):


    image.png
  5. Service
    由于我们的AIDL是跟Service配合使用的,所以我们就接着在Service中创建并调用,具体如下
    由于AIDL也是Binder的子类(有点忘了,我后续确认下嘿嘿嘿),所以只要通过binder新建个aidl的对象,然后自然就会重写我们aidl里的方法(这也是为什么我暂且将其作为接口看待的原因)


    Service

    然后记得在onBind()函数中将上述myBinder返回即可,至此Service部分就写完了

  6. Activity
    最后是我们的Activity,Activity部分也挺简单的
    我们只需要在onServiceConnected()中通过调用AIDL.Stub.asInterface(),并将该方法中的IBinder型参数传入即可,这样我们就获取到了我们的AIDL对象,而后续的事也就是通过该对象来调用之前写在里面的方法罢了


    Activity
  1. 结果


    image.png

2)添加监听

  1. 新建监听aidl文件:BookListener.aidl,并在其中完善监听接口


    BookListener.aidl
  2. 在BookManager.aidl中也添加注册和解绑监听的方法,记得需要显式导包


    BookManager.aidl
  3. Service中重写AIDL中两个新添加的方法以实现注册和解绑,并且模拟添加书籍


    重写方法

(模拟添加书籍可参照开发艺术探索P78)


模拟持续添加book
  1. Activity中获取BookListener的对象,并重写方法打印,然后记得调用bookManager.registerListener()即可


    2017-10-27-09-36-41.jpg
    2017-10-27-09-37-06.jpg
  2. 结果:
    可以从log里看到,当Activity销毁调用unregisterListener()时,无法找到之前注册的listener


    Log

PS:若Service和Activity在同一个进程的情况下,则不会有上述现象

3)使用RemoteCallbackList

由于我们的Service和Activity是在两个进程,而对象不能跨进程传输,而多进程跨进程的话,无法调取到同一对象,因为对象不能跨进程传输,所以Binder会把客户端传递过来的对象重新转换生成一个新的对象,
故若多进程时解绑,需要使用RemoteCallbackList

  1. 将listenerList类型从List改为RemoteCallbackList


    RemoteCallbackList
  2. 重写binder中的注册和解绑函数


    修改注册解绑方法

    需要注意的是RemoteCallbackList的size可以通过beginBroadcast()获取,但需要在调用后,调用finishBroadcast()


    RemoteCallbackList.begin
  3. 结果


    Log

项目地址:

遗留

  • AIDL里的in,out,inout三种类型
  • 由于上面只是知其然,还需要看官方文档知其所以然下

Refrence

  • 《Android开发艺术探索》

相关文章

网友评论

      本文标题:Aidl Lite

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