博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于使用AIDL出现空指针的解决办法
阅读量:5901 次
发布时间:2019-06-19

本文共 2456 字,大约阅读时间需要 8 分钟。

使用AIDL进行远程调用的时候出现的空指针异常,解决过程稍微有点小曲折。具体安下

1.先贴异常信息

1 ERROR/AndroidRuntime(9435): FATAL EXCEPTION: main2 ERROR/AndroidRuntime(9435): java.lang.NullPointerException3 ERROR/AndroidRuntime(9435): at android.os.Parcel.readException(Parcel.java:1328)4 ERROR/AndroidRuntime(9435): at android.os.Parcel.readException(Parcel.java:1276)

2.解析原因:看调用栈显示的是android.os.Parcel.readException位置出现了空指针异常,但是这是源代码啊,这里怎么会出空指针异常呢。好吧,要本看源码了:

1 public final void readException(int code, String msg) { 2         switch (code) { 3             case EX_SECURITY: 4                 throw new SecurityException(msg); 5             case EX_BAD_PARCELABLE: 6                 throw new BadParcelableException(msg); 7             case EX_ILLEGAL_ARGUMENT: 8                 throw new IllegalArgumentException(msg); 9             case EX_NULL_POINTER:10                 throw new NullPointerException(msg);11             case EX_ILLEGAL_STATE:12                 throw new IllegalStateException(msg);13         }14         throw new RuntimeException("Unknown exception code: " + code15                 + " msg " + msg);16     }

上面是出错的位置的代码。傻眼了,原来不是哪里有引用了空对象,而是它抛出了一个空指针异常。这是什么情况呢?

3.接着分析原因:追查readException方法调用的地方

1 @Override public java.lang.String doOperation() throws android.os.RemoteException 2 { 3 android.os.Parcel _data = android.os.Parcel.obtain(); 4 android.os.Parcel _reply = android.os.Parcel.obtain(); 5 java.lang.String _result; 6 try { 7 _data.writeInterfaceToken(DESCRIPTOR); 8 mRemote.transact(Stub.TRANSACTION_getMaxCpuFreq, _data, _reply, 0); 9 _reply.readException();10 _result = _reply.readString();11 }12 finally {13 _reply.recycle();14 _data.recycle();15 }16 return _result;17 }

关键代码是_reply.readException(); _reply为mRemote.transact()方法执行后的返回数据对象,即_reply为远程接口返回的数据封装对象。但是通过log查看,远程接口方法并没有执行完成啊,并没有返回数据啊,那怎么会有返回数据呢,而且返回通过返回数据对象抛出了空指针异常?

4.继续分析原因:由上可知远程方法并没有执行完成,但是transact方法却执行完成了,并且通过返回数据对象抛出了空指针,说明远程接口的api里面的实现是有问题的,它的问题导致了远程方法没有执行完成,直接返回。但是现在问题又来了,由于没有错误日志,没有调用栈信息,如果快速知道远程接口哪里代码出问题了呢。正在困惑的时候看到了国外的网站上给出了解决办法:

在远程实现接口的时候,实现onTransact方法,然后在里面捕获异常,并打印出调用栈的信息:

1 protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {2     try {3         super.onTransact(code, data, reply, flags);4     } catch (RuntimeException e) {5         Log.w("MyClass", "Unexpected remote exception", e);6         throw e;7     }8 }

原来是出现的exception是远端api实现中抛出来的,然后直接返回,将异常结果抛给了调用远端程序的客户端,原来如此。然后借助上面的调试代码打出的堆栈信息,直接定位,解决问题。

转载于:https://www.cnblogs.com/pillowzhou/p/4909281.html

你可能感兴趣的文章
黄聪:3分钟学会sessionStorage用法
查看>>
Entity Framework 全面教程详解(转)
查看>>
Windows上Python2.7安装Scrapy过程
查看>>
Chapter 3:Code Style in Django
查看>>
挖掘数据金矿 领军协同创新 曙光荣膺“2016大数据创新应用领袖企业”称号
查看>>
Fast通道获得Win10 Mobile Build 14977更新
查看>>
《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第3章3.6节识别操作系统...
查看>>
linux系统防火墙iptables命令规则及配置的示例
查看>>
10 个顶尖的 Linux 开源人工智能工具
查看>>
Firefox 跟踪保护技术将页面加载时间减少 44%
查看>>
聚合(根)、实体、值对象精炼思考总结
查看>>
java解析虾米音乐
查看>>
rails将类常量重构到数据库对应的表中之三
查看>>
mysql 多行合并函数
查看>>
【案例】RAID卡写策略改变引发的问题
查看>>
第四十八讲:tapestry 与 淘宝kissy editor编辑器带图片上传
查看>>
Linux/Centos 重置Mysql root用户密码
查看>>
[C语言]unicode与utf-8编码转换(一)
查看>>
利用PDO导入导出数据库
查看>>
DDR3
查看>>