今天在做一个有关AIDL的例子的时候,遇到一个小问题,死活两个进程就是无法通信。按着书上的例子做的(此处代码出自疯狂Android讲义第2版),还是出错,最后在网上查了下才知道是包名的问题。也就是说自己定义的那个AIDL接口所在的包的包名必须保持客户端和服务器端一致。否则会报错,程序强制退出。错误信息如下(事物绑定失败):
在调试模式下会看到如下异常(目标调用异常)抛出:
之所以这样是因为我的包名不一致,如下:
两者所在的包不一样,这是因为自己当时是直接复制的那个ICat.aidl文件,内容为:
1 package com.qc.aidlservice; 2 interface ICat 3 { 4 String getColor(); 5 double getWeight(); 6 }
因为其中涉及到导包,因为直接复制到服务端会报错,所以在服务端的文件中我把需要导入的包名改成了如下的包:
1 package com.example.myaidlclientdemo; 2 interface ICat 3 { 4 String getColor(); 5 double getWeight(); 6 }
但是这样就会出现上面所说的错误,其实这样多此一举反而造成了错误。最简单的做法就是在编写完服务器端代码后直接将AIDL文件所在的包原封不动的复制到我们的客户端。系统会自动为我们生成.java文件,简单方便。如下:
最后需要注意的就是配置service的时候,千万不能把service的属性配置成android:exported="false",此例中为:
1 <service android:name=".AidlService" 2 android:exported="false"> 3 <intent-filter > 4 <action android:name="com.example.myaidldemo.action.AIDL_SERVICE"/> 5 </intent-filter> 6 </service>
这样配置外部应用当然无法访问了啊(犯该错误的原因是在解决上篇博文里的警告问题是忘记改过来了,所以程序就一直强推,所以一定要细心细心再细心!!!)。
应该配置为:
1 <service android:name=".AidlService" 2 android:process=":remote"> 3 <intent-filter > 4 <action android:name="com.example.myaidldemo.action.AIDL_SERVICE"/> 5 </intent-filter> 6 </service>