Android cn.leancloud.AVException code=999 message=null

Android在使用leancloud数据存储服务时出现下面这个错误:

cn.leancloud.AVException code=999 message=null

查阅了官方文档,并没有错误码为999的说明,于是查看了一下AVException.java源码,找到了999这个错误码的常量描述:

public class AVException extends Exception {
 	  /**
	   * Error code indicating unknown reason.
	   */
	  public static final int UNKNOWN = 999;
}

看意思就是个未知错误,如果就这么放弃那就不是个合格的程序员了,于是继续挖源码,看看什么情况下对应的code值会变成这个UNKNOWN,发现这个code值都是AVException这个类的构造方法里赋值的:

/**
   * Construct a new AVException with a particular error code.
   *
   * @param theCode The error code to identify the type of exception.
   * @param theMessage A message describing the error in more detail.
   */
  public AVException(int theCode, String theMessage) {
    super(theMessage);
    this.code = theCode;
  }

  /**
   * Construct a new AVException with an external cause.
   *
   * @param message A message describing the error in more detail.
   * @param cause The cause of the error.
   */
  public AVException(String message, Throwable cause) {
    super(message, cause);
    if (cause instanceof AVException) {
      this.code = ((AVException) cause).getCode();
    } else {
      this.code = UNKNOWN;
    }
  }


  /**
   * Construct a new AVException with an external cause.
   *
   * @param cause The cause of the error.
   */
  public AVException(Throwable cause) {
    super(cause);
    if (cause instanceof AVException) {
      this.code = ((AVException) cause).getCode();
    } else {
      this.code = UNKNOWN;
    }
  }

于是把这几个构造方法都打上断点,看看是从哪里跳转过来的
在这里插入图片描述
于是来到了ErrorUtils.java这里:

public class ErrorUtils {
	 public static AVException propagateException(Throwable throwable) {
	    if (null == throwable) {
	      return null;
	    }
	    if (throwable instanceof HttpException) {
	      HttpException httpException = (HttpException) throwable;
	      if (null != httpException.response()) {
	        Response response = httpException.response();
	        if (null != response && null != response.errorBody()) {
	          try {
	            String content = response.errorBody().string();
	            AVException exception = ErrorUtils.propagateException(content);
	            return exception;
	          } catch (IOException ex) {
	            ;
	          }
	        }
	      }
	    }
	    //是这里跳转过去的
	    return new AVException(AVException.UNKNOWN, throwable.getMessage());
	  };
}

分析这个方法后发现,会先判断当前的异常throwable是否HttpException,如果不是的话那标记错误码为:AVException.UNKNOWN,也就是我们之前看到的999,所以我们想要看到真正的异常信息,就需要断点这个方法传进来的throwable对象:
在这里插入图片描述

真正的异常信息是这个:android.os.NetworkOnMainThreadException

这是Android里面常见的异常信息,也就是不能在主线程里进行网络请求,于是回头看看写的LoanCload相关代码:

AVQuery<AVObject>("question")
.findInBackground()
.subscribe({
    val datas = ArrayList<QuestionDataBean>()
    for (data: AVObject in it) {
        val tmp = QuestionDataBean()
        tmp.question = data["question"] as String
        tmp.answer = data["answer"] as String
        datas.add(tmp)
    }
    mAdapter.initData(datas)
})

那个findInBackground的意思不就是异步获取数据吗?难道还要我自己在Rxjava里指定io线程?于是手动给它指定了io线程后果然就不报错了:

AVQuery<AVObject>("question")
.findInBackground()
.subscribeOn(Schedulers.io())//这里指定在io线程执行
.observeOn(AndroidSchedulers.mainThread())//返回结果在主线程执行
.subscribe({
    val datas = ArrayList<QuestionDataBean>()
    for (data: AVObject in it) {
        val tmp = QuestionDataBean()
        tmp.question = data["question"] as String
        tmp.answer = data["answer"] as String
        datas.add(tmp)
    }
    mAdapter.initData(datas)
})

总结:

1、都是leancloud的坑,文档不够详细,没有找到Android Rxjava相关示例
2、 findInBackground容易给人误导,让人以为已经指定了io线程异步执行
3、错误提示不够完善,throwable.getMessage()如果返回来的是null值,就应该再把其他异常信息保存起来,比如这次的android.os.NetworkOnMainThreadException异常

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值