zoukankan      html  css  js  c++  java
  • 关于使用AIDL出现空指针的解决办法

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

    1.先贴异常信息

    1 ERROR/AndroidRuntime(9435): FATAL EXCEPTION: main
    2 ERROR/AndroidRuntime(9435): java.lang.NullPointerException
    3 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: " + code
    15                 + " 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实现中抛出来的,然后直接返回,将异常结果抛给了调用远端程序的客户端,原来如此。然后借助上面的调试代码打出的堆栈信息,直接定位,解决问题。

  • 相关阅读:
    vim编辑器基本操作及文件权限,sudo命令等介绍
    centos的基本命令04
    linux的sed(增删改查)使用方法
    rm: cannot remove `xxx’: Operation not permitted问题的处理方案
    迅为iTOP-4412物联网开发板入门学习高手进阶项目开发超树莓派
    迅为I.MX6Q开发板配不同分辨率不同尺寸液晶屏幕
    iTOP-4412开发板-实战教程-ssh服务器移植到arm开发板
    iTOP-4412开发板全新升级支持4G全网通模块
    迅为iMX6UL开发板低功耗高能效开发平台
    iTOP-4418/6818开发板支持双屏异显,双屏同显
  • 原文地址:https://www.cnblogs.com/pillowzhou/p/4909281.html
Copyright © 2011-2022 走看看