org.xutils.http.loader.ObjectLoader
import android.text.TextUtils;
import org.xutils.cache.DiskCacheEntity;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.ParameterizedTypeUtil;
import org.xutils.http.RequestParams;
import org.xutils.http.annotation.HttpResponse;
import org.xutils.http.app.InputStreamResponseParser;
import org.xutils.http.app.ResponseParser;
import org.xutils.http.request.UriRequest;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
/**
* @author 注释者:王教成
* @version 注释版:1.0.0
* 对象加载器,其他对象的下载转换,使用类型上的HttpResponse注解信息进行数据转换
*/
/*package*/ class ObjectLoader extends Loader<Object> {
private String charset = "UTF-8";//创建UTF-8字符集字符串
private String resultStr = null;//声明结果字符串
private final Type objectType;//声明对象类型
private final Class<?> objectClass;//声明对象类
private final ResponseParser parser;//声明响应分析器
public ObjectLoader(Type objectType) {
this.objectType = objectType;//对对象类型初始赋值
{
if (objectType instanceof ParameterizedType) {
objectClass = (Class<?>) ((ParameterizedType) objectType).getRawType();//如果对象类型属于参数化类型,强转参数化类型,再强转Class类型,获取原始类型作为对象类型
} else if (objectType instanceof TypeVariable) {
throw new IllegalArgumentException(
"not support callback type " + objectType.toString());//如果对象类型属于类型变量,抛出非法参数异常
} else {
objectClass = (Class<?>) objectType;//都不属于则强转Class类型作为对象类型
}
}//检查加载类型和结果类型代码块
if (List.class.equals(objectClass)) {
Type itemType = ParameterizedTypeUtil.getParameterizedType(this.objectType, List.class, 0);//如果对象类型是列表类型,获取泛型类型作为实体类型
Class<?> itemClass = null;//声明实体类
if (itemType instanceof ParameterizedType) {
itemClass = (Class<?>) ((ParameterizedType) itemType).getRawType();//如果实体类型属于参数化类型,强转参数化类型,再强转Class类型,获取原始类型作为实体类型
} else if (itemType instanceof TypeVariable) {
throw new IllegalArgumentException(
"not support callback type " + itemType.toString());//如果实体类型属于类型变量,抛出非法参数异常
} else {
itemClass = (Class<?>) itemType;//都不属于则强转Class类型作为实体类型
}
HttpResponse response = itemClass.getAnnotation(HttpResponse.class);//用实体类型获取网络响应注解
if (response != null) {
try {
this.parser = response.parser().newInstance();//如果网络响应注解非空,获取分析器创建新实例
} catch (Throwable ex) {
throw new RuntimeException("create parser error", ex);//捕获异常,抛出运行时异常
}
} else {
throw new IllegalArgumentException("not found @HttpResponse from " + itemType);//如果网络响应注解为空,抛出非法参数异常
}
} else {
HttpResponse response = objectClass.getAnnotation(HttpResponse.class);//用对象类型获取网络响应注解
if (response != null) {
try {
this.parser = response.parser().newInstance();//如果网络响应注解非空,获取分析器创建新实例
} catch (Throwable ex) {
throw new RuntimeException("create parser error", ex);//捕获异常,抛出运行时异常
}
} else {
throw new IllegalArgumentException("not found @HttpResponse from " + this.objectType);//如果网络响应注解为空,抛出非法参数异常
}
}
}//构造器
/**
* 创建新实例
* @return 不能返回Object对象加载器,抛出非法访问错误
*/
@Override
public Loader<Object> newInstance() {
throw new IllegalAccessError("use constructor create ObjectLoader.");//抛出非法访问错误
}
/**
* 设置请求参数
* @param params 请求参数
*/
@Override
public void setParams(final RequestParams params) {
if (params != null) {
String charset = params.getCharset();//如果请求参数非空,从请求参数获取字符集
if (!TextUtils.isEmpty(charset)) {
this.charset = charset;//如果字符集非空则赋值
}
}
}
/**
* 加入输入流
* @param in 输入流
* @return 返回Object对象
* @throws Throwable 抛出异常
*/
@Override
public Object load(final InputStream in) throws Throwable {
Object result;//声明Object对象
if (parser instanceof InputStreamResponseParser) {
result = ((InputStreamResponseParser) parser).parse(objectType, objectClass, in);//如果属于输入流响应分析器,强转将输入流转换为Object对象
} else {
resultStr = IOUtil.readStr(in, charset);//如果不属于输入流响应分析器,从输入流读取字符串
result = parser.parse(objectType, objectClass, resultStr);//将字符串转换为Object对象
}
return result;
}
/**
* 加载Uri请求参数
* @param request Uri请求参数
* @return 返回Object对象
* @throws Throwable 抛出异常
*/
@Override
public Object load(final UriRequest request) throws Throwable {
try {
request.sendRequest();//发送请求
} finally {
parser.checkResponse(request);//用响应分析器检查请求参数的响应
}
return this.load(request.getInputStream());//通过Uri请求参数获取输入流,调用本类加载输入流方法
}
/**
* 加载,从磁盘缓存实体
* @param cacheEntity 磁盘缓存实体
* @return 返回Object对象或null
* @throws Throwable 抛出异常
*/
@Override
public Object loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable {
if (cacheEntity != null) {
String text = cacheEntity.getTextContent();//如果磁盘缓存实体非空,获取文本内容
if (!TextUtils.isEmpty(text)) {
return parser.parse(objectType, objectClass, text);//如果文本内容非空,用响应分析器转换文本为Object对象
}
}
return null;
}
/**
* 保存到缓存实体
* @param request Uri请求参数
*/
@Override
public void save2Cache(UriRequest request) {
saveStringCache(request, resultStr);//保存字符串缓存
}
}