赞
踩
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异常
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。