您的位置:首页 > 理论基础 > 计算机网络

Android通用网络请求解析框架.8(同步请求,分支部分)

2017-01-06 18:23 525 查看
笔者将通过11篇博客对个人开源框架进行讲解,本篇为第8篇,讲解支持同步请求,分支部分。

开源库github地址 https://github.com/qq296216078/Android-Universial-NetFrame

如果有兴趣一起讨论本框架的内容,请加QQ群:271335749

上一篇中我们已经完成了同步请求公共部分的代码实现,核心监听器的代码是这样的
abstract public class SyncNetHandleListener implements SyncNetListener {
protected NetRetBean handleResult(NetRetBean netRetBean) {
return netRetBean;
}

@Override
public NetRetBean sendSuccess(String result) {
NetRetBean netRetBean = new NetRetBean();
try {
JSONObject jsonObject = new JSONObject(result);
String code = jsonObject.getString("code");
String message = jsonObject.getString("message");
String time = jsonObject.getString("time");
String data = jsonObject.getString("data");
netRetBean.setServerCode(code);
netRetBean.setServerMsg(message);
netRetBean.setServerTime(time);
netRetBean.setServerData(data);
if (code.equals("00001")) {
netRetBean.setCallbackCode(CallbackCode.CODE_SUCCESS_REQUEST);
netRetBean = onReceivedRet(netRetBean);
} else {
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_SERVER_DATA_ERROR);
}
} catch (JSONException e) {
e.printStackTrace();
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_JSON_EXP);
}
return handleResult(netRetBean);
}

@Override
public NetRetBean sendError(Exception exp) {
exp.printStackTrace();

NetRetBean netRetBean = new NetRetBean();
netRetBean.setException(exp);

try {
throw exp;
} catch (RespondErrorException e) {
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_HTTP_NOT_200);
} catch (RequestErrorException e) {
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_REQUEST_EXP);
} catch (JSONException e) {
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_JSON_EXP);
} catch (Exception e) {
netRetBean.setCallbackCode(CallbackCode.CODE_ERROR_UNKNOWN);
}

return handleResult(netRetBean);
}

abstract protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException;
}

使用上SyncNetHandleListener,会是这样的
private void syncGetString() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetHandleListener() {
@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
return null;
}
});
}
}.start();
}


还是存在代码执行顺序模糊的问题。还有内层数据的解析,需要开发者自己来完成。
如果在onReceivedRet回调的解析方法中直接返回null,那么在返回的NetRetBean的内层数据还是为null。

为了不让使用者来实现内层数据的解析,所以就应该在框架内部实现内层数据的解析。
那应该怎样在框架内部进行解析呢?学异步请求就好了,继承SyncNetHandleListener,来看看子类中是怎样解析数据的
package com.chenjian.net.listener.sync;

import com.chenjian.net.bean.NetRetBean;

import org.json.JSONException;

/**
* 返回字String的网络请求Listener
* <p>
* 作者: ChenJian
* 时间: 2016.12.15 14:54
*/

public class SyncNetStringListener extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
netRetBean.setServerObject(netRetBean.getServerData());
return handleResult(netRetBean);
}
}


这里的handleResult是父类的方法,根据之前的代码,父类这个方法只是将NetRetBean原封不动的返回。
因为父类中定义抽象方法onReceivedRet时需要返回值,所以这里需要将内层数据进行解析,然后再返回。
还有一个变化,因为本类不存在抽象方法,所以本类也不是抽象类了,不要在类的前面加上abstract。

对比一下异步请求的代码实现
abstract public class NetStringListener extends NetHandleListener {

@Override
protected void onReceivedRet(NetRetBean netRetBean) throws JSONException {
netRetBean.setServerObject(netRetBean.getServerData());
handleResult(netRetBean);
}

@SuppressWarnings("unchecked")
@Override
protected void onSuccess(CallbackCode successCode, NetRetBean netRetBean) {
onSuccess((String) netRetBean.getServerObject());
}

/**
* 运行在ui线程,返回单个实体
*
* @param string 当前string
*/
abstract protected void onSuccess(String string);
}


可以看到,同步请求的时候,因为父类没有onSuccess方法,也不需要回调,所以同步请求代码实现起来更简单,只是将解析后的结果进行返回就可以了。
正如上面所说,同步请求的Listener不是抽象类,不要加abstract修饰类,

其它监听器也需要做类似的修改,继承SyncNetHandleListener,我们实现了SyncNetSingleBeanListener
package com.chenjian.net.listener.sync;

import com.chenjian.net.bean.NetBaseBean;
import com.chenjian.net.bean.NetRetBean;
import com.chenjian.net.util.NetBaseBeanUtil;

import org.json.JSONException;
import org.json.JSONObject;

/**
* 返回是单个Bean的网络请求Listener
* <p>
* 作者: ChenJian
* 时间: 2016.12.15 14:54
*/

public class SyncNetSingleBeanListener<T extends NetBaseBean> extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
JSONObject object = new JSONObject(netRetBean.getServerData());
T t = NetBaseBeanUtil.parseItem(getClass(), 0, object);
netRetBean.setServerObject(t);
return handleResult(netRetBean);
}
}


再实现SyncNetListBeanListener
package com.chenjian.net.listener.sync;

import com.chenjian.net.bean.NetBaseBean;
import com.chenjian.net.bean.NetRetBean;
import com.chenjian.net.util.NetBaseBeanUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
* 返回是List<Bean>的网络请求Listener
* <p>
* 作者: ChenJian
* 时间: 2016.12.15 14:54
*/

public class SyncNetListBeanListener<T extends NetBaseBean> extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
JSONArray array = new JSONArray(netRetBean.getServerData());
List<T> list = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
T t = NetBaseBeanUtil.parseItem(getClass(), 0, object);
list.add(t);
}
netRetBean.setServerObject(list);
return handleResult(netRetBean);
}
}


可以看到,同步请求分支部分的代码和异步请求时差不多,只是父类不一样,还有最后需要将结果进行返回,而不是回调。

到此,框架中同步请求的代码都已经添加完成,可以开始使用了
private void syncGetString() {
new Thread() {
@Override
public void run() {
String originalString = NetHelper.getStringSync("url");
System.out.println(originalString);

NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetStringListener());
CallbackCode callbackCode = netRetBean.getCallbackCode();
switch (callbackCode) {
case CODE_SUCCESS_REQUEST:
String string = (String) netRetBean.getServerObject();
System.out.println(string);
break;
case CODE_ERROR_HTTP_NOT_200:
case CODE_ERROR_REQUEST_EXP:
case CODE_ERROR_SERVER_DATA_ERROR:
case CODE_ERROR_JSON_EXP:
case CODE_ERROR_UNKNOWN:
default:
System.out.println(netRetBean.toString());
break;
}
}
}.start();
}


getStringSync返回的是最原始的数据,没有经过解析的,他不需要传入监听器参数。
getSync返回的是NetRetBean,传入的监听器类型的不同,NetRetBean中serverObject类型也会不同。当然这里需要开发者自己取出来进行强转。

笔者一开始想把serverObject对象的类型变成泛型,后来发现如果是自定义监听器进行同步请求时,一个泛型对象不够通用,还是得用到serverObjectMap属性才行。

回顾上一篇中的需求,根据url1请求的结果判断是否请求url2,我们可以这样实现
private void syncGetString() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.getSync("url1", new SyncNetStringListener());
if (netRetBean.isSuccess()) {
NetHelper.getSync("url2", new SyncNetStringListener());
}

try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}


这样的话,代码的执行顺序就很清晰了,返回值的方式也非常符合同步请求的需求,代码看起来简单明了。

我们接着再来使用其它的Listener来完成同步请求。

假设服务端返回的数据是这样的:
{
"code":"00001",
"message":"login success",
"time":"1479807260",
"data":{
"id":"123",
"name":"chenjian"
}
}


NetUserBean的代码与之前的一样,没有改变

public class NetUserBean extends NetBaseBean {
private String id;
private String name;

@Override
public void initByJson(JSONObject jsonObject) throws JSONException {
this.id = jsonObject.optString("id");
this.name = jsonObject.optString("name");
}
}


开始使用
private void syncGetBean() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetSingleBeanListener<NetUserBean>());
CallbackCode callbackCode = netRetBean.getCallbackCode();
switch (callbackCode) {
case CODE_SUCCESS_REQUEST:
NetUserBean userBean = (NetUserBean) netRetBean.getServerObject();
System.out.println(userBean.toString());
break;
default:
System.out.println(netRetBean.toString());
break;
}
}
}.start();
}


居然报错了
NetRetBean{
mCallbackCode=CODE_ERROR_UNKNOWN,
mException=java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType,
mServerCode='null', mServerMsg='null', mServerTime='null', mServerData='null', mServerObject=null, mServerObjectMap=null}


再细看异常信息
01-11 13:35:45.470 2432-3428/com.chenjian.net W/System.err: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.util.NetBaseBeanUtil.getBean(NetBaseBeanUtil.java:41)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.util.NetBaseBeanUtil.parseItem(NetBaseBeanUtil.java:28)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.listener.sync.SyncNetSingleBeanListener.onReceivedRet(SyncNetSingleBeanListener.java:30)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.listener.sync.SyncNetHandleListener.sendSuccess(SyncNetHandleListener.java:46)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.core.sync.SyncNetExcutor.startRequest(SyncNetExcutor.java:83)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.core.sync.SyncNetExcutor.get(SyncNetExcutor.java:64)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.helper.NetHelper.getSync(NetHelper.java:96)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.helper.NetHelper.getSync(NetHelper.java:80)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.demo.activity.GetActivity$5.run(GetActivity.java:189)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.util.NetBaseBeanUtil.getBean(NetBaseBeanUtil.java:41)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.util.NetBaseBeanUtil.parseItem(NetBaseBeanUtil.java:28)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.listener.sync.SyncNetSingleBeanListener.onReceivedRet(SyncNetSingleBeanListener.java:30)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.listener.sync.SyncNetHandleListener.sendSuccess(SyncNetHandleListener.java:46)
01-11 13:35:45.471 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.core.sync.SyncNetExcutor.startRequest(SyncNetExcutor.java:83)
01-11 13:35:45.472 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.core.sync.SyncNetExcutor.get(SyncNetExcutor.java:64)
01-11 13:35:45.472 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.helper.NetHelper.getSync(NetHelper.java:96)
01-11 13:35:45.472 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.helper.NetHelper.getSync(NetHelper.java:80)
01-11 13:35:45.472 2432-3428/com.chenjian.net W/System.err:     at com.chenjian.net.demo.activity.GetActivity$5.run(GetActivity.java:189)


重点在于这两行
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.chenjian.net.util.NetBaseBeanUtil.getBean(NetBaseBeanUtil.java:41)


我们再看看NetBaseBeanUtil的41行代码
Class<T> entityClass = (Class<T>) ((ParameterizedType) aClass.getGenericSuperclass()).getActualTypeArguments()[tIndex];


很明显的看出来了,aClass.getGenericSuperclass后,是一个Object类型,不能强转为ParameterizedType。
可是之前的SyncNetStringListener为什么没有报错呢?因为SyncNetStringListener并没有用到NetBaseBeanUtil,只是将数据解析为String类型,而不需要使用到NetBaseBeanUtil方法来获取Bean。

那又为什么异步请求时都没问题,而在这个地方就有问题呢?

回忆一下第4篇中提到的java泛型去参数化的概念,我们再来看看NetBaseBeanUtil的代码
public class NetBaseBeanUtil {

/**
* @param aClass     带泛型 T 的类,应该传入xxBeanListener监听器或其的子类。他的父类必须是带泛型T的
* @param tIndex     泛型 T 所在下标
* @param jsonObject 用来解析的 json
* @param <T>        泛型 T
* @return 返回泛型T的实例
* @throws JSONException
*/
public static <T extends NetBaseBean> T parseItem(Class aClass, int tIndex, JSONObject jsonObject) throws JSONException {
T t = getBean(aClass, tIndex);
t.initByJson(jsonObject);
return t;
}

/**
* @param aClass 带泛型 T 的类,应该传入xxBeanListener监听器或其的子类。他的父类必须是带泛型T的
* @param tIndex 泛型 T 所在下标
* @param <T>    泛型 T
* @return 返回泛型T的实例
*/
@SuppressWarnings("unchecked")
private static <T extends NetBaseBean> T getBean(Class aClass, int tIndex) {
Class<T> entityClass = (Class<T>) ((ParameterizedType) aClass.getGenericSuperclass()).getActualTypeArguments()[tIndex];
T entity = null;
try {
// 使用newInstance创建实例的类,必须有无参构造方法
entity = entityClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return entity;
}
}


正如注释所说,这里的aClass的父类必须是带泛型的,而在使用异步请求的时候,因为需要回调,通常的做法是new一个Listener为内部类。而内部类实际上编译器会先定义一个类继承于他,然后再将那个类传入当参数。而同步请求,而直接new一个对象出来,并没有使用他的子类。一起来通过代码对比一下

异步请求我们使用内部类,其实get方法的第二个参数的类型,是NetSingleBeanListener的子类
NetHelper.get("url", new NetSingleBeanListener<NetUserBean>() {
@Override
protected void onError(CallbackCode errorCode, NetRetBean netRetBean) {

}

@Override
protected void onSuccess(NetUserBean userBean) {

}
});


同步请求时,我们直接生成一个SyncNetStringListener的对象
NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetSingleBeanListener<NetUserBean>());


在两个Listener中,我们在使用NetBaseBeanUtil时,都调用了下面这一行代码
T t = NetBaseBeanUtil.parseItem(getClass(), 0, object);

getClass()非常重要,
在NetSingleBeanListener中,如果是他的子类调用了这个方法,那么返回的是他的子类
在SyncNetSingleBeanListener中,只是本类调用了这个方法,所以返回的是这个类本身


而这个时候,在NetBaseBeanUtil的getBean方法中,需要用到aClass.getGenericSuperclass,对传入的class对象进行操作,

如果传入的aClass是NetSingleBeanListener的子类,那么得到的父类是NetSingleBeanListener,他是带泛型的,可以通过代码取出泛型的类型,再反射
如果传入的aClass是SyncNetSingleBeanListener类,那么得到的父类是SyncNetHandleListener,他是不带泛型的,通过代码取出泛型时就会出错

那既然出现了问题,有办法能解决吗?总不能让同步请求实现不了吧。

一开始,我想到的是,不用getGenericSuperclass的方式取出泛型,而直接在aClass类中取出泛型,但是查阅相关资料后,发现这不可能的。

因为Java泛型去参数化(擦拭法)的原因,只有在 
超类(调用 getGenericSuperclass 方法)

或者成员变量(调用 getGenericType 方法)

或者方法(调用 getGenericParameterTypes 方法)

像这些有方法返回 ParameterizedType 类型的时候才能反射成功


所以使用的时候,必须使用他的子类,而不能直接使用本类。

可以说这非常蛋疼,但你又不得不遵守这样的规则。

那还有其它办法可以解决这个问题吗?显然是有的,只要学习异步请求,用子类就行了。

笔者一开始是直接继承SyncNetSingleBeanListener来实现一个类,假设为MyListener吧,类里面是空的。然后传参的时候,new MyListener(),发现不行的,单步调试时发现aClass.getGenericSuperclass时,居然还是SyncNetHandleListener,没有深入去研究,笔者猜想是编译器直接把这个空的MyListener类给删除掉了。

于是为了让开发者使用框架的时候不混乱,知道要使用哪个Listener,我想到了另一种办法。

还是学异步请求,直接把SyncNetSingleBeanListener定义为抽象类
package com.chenjian.net.listener.sync;

import com.chenjian.net.bean.NetBaseBean;
import com.chenjian.net.bean.NetRetBean;
import com.chenjian.net.util.NetBaseBeanUtil;

import org.json.JSONException;
import org.json.JSONObject;

/**
* 返回是单个Bean的网络请求Listener
* <p>
* 由于去参数化(擦拭法),也只有在
* 超类(调用 getGenericSuperclass 方法)
* 或者成员变量(调用 getGenericType 方法)
* 或者方法(调用 getGenericParameterTypes 方法)
* 像这些有方法返回 ParameterizedType 类型的时候才能反射成功
* <p>
* 所以使用的时候,必须使用他的子类,而不能直接使用本类
* <p>
* 作者: ChenJian
* 时间: 2016.12.15 14:54
*/

abstract public class SyncNetSingleBeanListener<T extends NetBaseBean> extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
JSONObject object = new JSONObject(netRetBean.getServerData());
T t = NetBaseBeanUtil.parseItem(getClass(), 0, object);
netRetBean.setServerObject(t);
return handleResult(netRetBean);
}
}


这样一来,在使用他的时候,不能直接new,因为抽象类不能生成对象,必须使用他的子类才可以,不然不能编译通过。
一般开发者可以用内部类的方式,其实也是用到了他的子类
private void syncGetBean() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetSingleBeanListener<NetUserBean>() {
});
CallbackCode callbackCode = netRetBean.getCallbackCode();
switch (callbackCode) {
case CODE_SUCCESS_REQUEST:
NetUserBean userBean = (NetUserBean) netRetBean.getServerObject();
System.out.println(userBean.toString());
break;
default:
System.out.println(netRetBean.toString());
break;
}
}
}.start();
}


使用内部类时,只要加一对花括号{}就可以了,因为里面没有未实现的抽象方法,所以花括号里面是空的。

同样,对于SyncNetListBeanListener,我们也定义为抽象类
package com.chenjian.net.listener.sync;

import com.chenjian.net.bean.NetBaseBean;
import com.chenjian.net.bean.NetRetBean;
import com.chenjian.net.util.NetBaseBeanUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
* 返回是List<Bean>的网络请求Listener
* <p>
* 由于去参数化(擦拭法),也只有在
* 超类(调用 getGenericSuperclass 方法)
* 或者成员变量(调用 getGenericType 方法)
* 或者方法(调用 getGenericParameterTypes 方法)
* 像这些有方法返回 ParameterizedType 类型的时候才能反射成功
* <p>
* 所以使用的时候,必须使用他的子类,而不能直接使用本类
* <p>
* 作者: ChenJian
* 时间: 2016.12.15 14:54
*/

abstract public class SyncNetListBeanListener<T extends NetBaseBean> extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
JSONArray array = new JSONArray(netRetBean.getServerData());
List<T> list = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
T t = NetBaseBeanUtil.parseItem(getClass(), 0, object);
list.add(t);
}
netRetBean.setServerObject(list);
return handleResult(netRetBean);
}
}


在使用时也很简单
private void syncGetListBean() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.getSync("url", new SyncNetListBeanListener<NetUserBean>() {
});
CallbackCode callbackCode = netRetBean.getCallbackCode();
switch (callbackCode) {
case CODE_SUCCESS_REQUEST:
List<NetUserBean> userBeen = (List<NetUserBean>) netRetBean.getServerObject();
for (int i = 0; i < userBeen.size(); i++) {
System.out.println(userBeen.get(i).toString());
}
break;
default:
System.out.println(netRetBean.toString());
break;
}
}
}.start();
}


到这里,框架内的同步请求代码已经全部完成。

最后再来回忆一下第6篇的内容,讲的是自定义解析器,其实现方案也只能适合异步请求,那么在同步请求时,我们只要学着SyncNetSingleBeanListener的实现思路,进行一些修改就行
package com.chenjian.net.demo.listener.sync;

import com.chenjian.net.bean.NetBaseBean;
import com.chenjian.net.bean.NetRetBean;
import com.chenjian.net.listener.sync.SyncNetHandleListener;
import com.chenjian.net.util.NetBaseBeanUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 作者: ChenJian
* 时间: 2016.12.16 13:51
*/

abstract public class SyncNetCustomBeanListener<Page extends NetBaseBean, T extends NetBaseBean> extends SyncNetHandleListener {

@Override
protected NetRetBean onReceivedRet(NetRetBean netRetBean) throws JSONException {
JSONObject jsonObject = new JSONObject(netRetBean.getServerData());

Page page = NetBaseBeanUtil.parseItem(getClass(), 0, jsonObject);

List<T> list = new ArrayList<>();
JSONArray jsonArray = jsonObject.getJSONArray("list");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
T t = NetBaseBeanUtil.parseItem(getClass(), 1, object);
list.add(t);
}

Map<String, Object> map = new HashMap<>();
map.put("page", page);
map.put("list", list);

netRetBean.setServerObjectMap(map);
return handleResult(netRetBean);
}
}


使用起来是这样的
private void syncCustom() {
new Thread() {
@Override
public void run() {
NetRetBean netRetBean = NetHelper.postSync("url", "param", new SyncNetCustomBeanListener<NetPageBean, NetInfoBean>() {
});
CallbackCode callbackCode = netRetBean.getCallbackCode();
switch (callbackCode) {
case CODE_SUCCESS_REQUEST:
Map<String, Object> map = netRetBean.getServerObjectMap();
NetPageBean pageBean = (NetPageBean) map.get("page");
List<NetInfoBean> infoBeen = (List<NetInfoBean>) map.get("list");
System.out.println(pageBean.toString());
for (int i = 0; i < infoBeen.size(); i++) {
System.out.println(infoBeen.get(i).toString());
}
break;
default:
System.out.println(netRetBean.toString());
break;
}
}
}.start();
}

使用的时候,因为监听器内部的实现,要使到具体数据的话,要从NetRetBean的serverObjectMap里面取,map的key的值根据SyncNetCustomBeanListener中定义的一样。

总结一下,
当所使用的Listener需要调用NetBaseBeanUtil时,就要实现成抽象类,在使用这类监听器时,要使用他的子类。此处的例子有SyncNetSingleBeanListener,SyncNetListBeanListener,SyncNetCustomBeanListener。
当所使用的Listener不需要调用NetBaseBeanUtil时,就不要实现成抽象类了,在使用这类监听器时,直接创建他的对象。此处的唯一例子就是SyncNetStringListener。

可以说在开发者的角度,使用本框架进行异步请求或者同步请求差别并不大,只是入口从get变成getSync,post变成postSync,监听器也换成了相应的就行了。还要注意的是在自定义监听器时,如果开发者有需要使用到同步请求,也要实现一个同步请求的自定义解析器。如果不需要,就不要实现了。

至此,同步请求的所有内容都已讲解完成。

下一篇将讲解对第三方解析框架的支持
Android通用网络请求解析框架.9(支持第三方解析框架)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: