项目网络框架android-async-http分析

本文详细解析了Loopj网络请求框架的工作原理及使用方法,包括请求参数、结果处理及泛型的应用等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实使用这个网络加载框架loopj很简单:简单来说就是:你给我参数,以及你想要的返回结果result对象,那么我接收你的参数处理之后返回给你,你需要的result对象。(这之间的处理过程另说)
项目中发现的继承体系有三个:
其一:网络请求参数的继承体系,根据具体的业务,从对应业务的请求参数开始,层层往上对请求参数进行封装,最终成为一个完整的网络请求的参数。
其二:网络请求结果继承体系,最顶层是一个监听器:RequestListener,这个体系是我们想要将网络请求结果(成功、失败)的业务逻辑独立出来的结果,各个具体的业务针对网络请求成功(返回result对象)和失败的处理,通过这个体系来完成
其三:那么在你给人家请求参数到你得到你想要的返回结果request,这之间也是需要一些额外的处理的,这就涉及到了第三个继承体系,JsonParseProxy(特殊json处理)体系


那么在这整个过程里面我们需要由控制上面整个流程的处理类:
AsyncHttpHandlerProxy:其功能就是上接框架请求返回的请求结果,下接处理结果的处理体系,其作用就是:将返回的结果Byte[ ]数组,转成request对象的过程。



8.网络请求的返回数据bytes,是如何变成我们的适配器需要的Bean对象里面包括的集合数据的?

 在AsyncHttpHandlerProxy类里面当访问网络成功之后会调用onSuccess()方法,在这个方法里面会调用JSON.parseObjectbytes,mClass)方法将数据bytes转成我们需要的Bean对象,并且将这个bean传给requestListeneronRequestSuccess()方法,而BaseNetPageAdapter实现了这个方法,于是转而调用此类的这个方法,在这个方法里面其将bean数据中的集合数据取出。并复制给自己的集合

8.景点列表页面的数据加载显示的过程是:先设置组件下滑列表的Adapter,配置网络请求参数,然后使用TCViewSpotListAdapter类去加载数据,当数据加载成功之后,会在适配器的OnRequestSuccess()方法里面,将返回的数据调用方法将其解析

 

10.这里是怎么使用泛型的?

这里的网络请求的过程中使用到了泛型,比如这里网络列表请求的基类BaseListResult<T>类就使用了泛型,有什么作用呢?比如其子类同城列表页面的封装请求参数的TCViewSpotListResp类,因为这个类是业务相关的类因此在这个类里面其定义了一个List列表List<TCViewSpotBean>,这个列表就是用来存放解析之后得到的TCViewSpotBean对象的集合的,而其继承父类的时候就穿进去了一个参数BaseListResult<TCViewSpotBean>其作用就类似你使用了HashMap例如:

Map<String, String> map = new HashMap<String, String>();这样声明了之后如果其他地方向里面存值就只能是String类型的,二不能是其他类型的,

不过这个框架的用法不是如此:在BaseListResult里面有这样一个方法;

public abstract List<T> getListData();

在这里使用泛型的好处就是:当某个地方调用这个方法的时候,我们规定了其返回的值必须是一个集合而且类型必须是TList<T>,对这里来说就是必须是List<TCViewSpotBean>,而继承的好处就是:不同的子类传递过来的参数不同那么返回的类型就不同,继承的一个很大的用处就是对继承体系进行规范

 

11.接着上面说泛型:

首先更改你的一个错误的认识,如下面的这一段代码,

BaseNetPageAdapter<T, M extends BaseListResult<T>>这样的写法并不是说TM都是这个extends BaseListResult<T>,而是说T我不限制但是M必须要是BaseListResult的子类,但是这里仅仅只是规定了,如果你要忘我里面放东西的话,必须是按照我的这个规则来,但是什么时候放东西呢?这就要说到继承的好处了,我们知道这个BaseNetPageAdapter类是基类是不涉及业务的类,那么我们就可以在其涉及业务场景的子类里面在继承的时候,声明出来你所需要的TM到底是什么,同样可以参考List<T>的用法,当我们创建创建一个List<String>的时候,我们看到所有的List类里面操作数据存入的方法,都添加了一个判断,判断你添加的数据是否和你声明的String一致,若不则不能添加,又因为JAVA系统是支持做判断的,因此我们可以利用这一点限制我们进出的数据必须是我们想要的数据,至于你所担心的JAVA怎么将T和你设置的StringList类里面是如何自动等价起来的,暂时不需要你操心。

(网络请求框架:loopj

4.FocusHttpClientHttp请求类(单例模式),业务模块直接调用该类进行Http网络请求模块,该类有两个方法:requestPostContext context, BaseRequestParams params, RequestListener<T> listener, JsonParserProxy jsonParserProxy)和requestGet(),当业务模块进行网络请求的时候,直接调用这两个并传入对应的参数,这两个方法接收了参数,直接使用这些参数进行HttpProxy(接口)的requestGetrequestPost方法的调用。HttpProxy的实现类只有一个AsyncHttpProxy,其中实现了这两个方法

 

例如:当我们使用BaseNetPageAdapter类进行网络请求的时候,调用FocusHttpClientrequestGet的方法,在这个方法里面FocusHttpClient调用了HttpProxy(接口)的requestGet方法,于是执行此接口的实现类AsyncHttpProxy类的requestGet方法,在这个方法里面我们使用网络请求框架loopjAsyncHttpClient类的get()方法,进行请求网络数据操作,其必须要需的一个方法参数是:responseHandlerInterface的实现类(用与接收网络请求的结果),这里使用的是继承了AsyncHttpResponseHandler类(实现了responseHandlerInterface)的自定义类AsyncHttpHandlerProxy来处理网络请求返回的数据(一般重写onSuccess()和onFailure()方法。

接着:当网络请求成功了的时候,AsyncHttpHandlerProxy类的onSuccess()方法会执行,在这个方法里面会调用一个监听器RequestListenreronRequestSuccess()方法,而BaseNetPageAdapterimplements(实现)了这个接口,因此会调用其覆盖接口的onRequestSuccess()方法,

至此形成了一个循环:BaseNetPageAdapter进行网络数据请求,请求成功之后,调用其onRequestSuccess()方法执行之后的操作。

另附:

在网络请求框架loopj中接收网络请求结果的类AsyncHttpHandlerProxy会在onSuccess()方法方法中执行将网络返回的数据byte[ ]转换成数据模型bean的过程,因此构建这个类必须要有的参数之一就是:Class mClass (代表的是数据模型bean类)

因此:你去观察这个mClass 参数是由getResponseClass()方法来获得的,而根据继承关系最终需要由TCViewSpotDetailReq类来实现这个方法,因此这个方法的返回值就是你需要的得到的数据bean对象。

 

5.监听器负责的是什么时候去加载这个interface里面的方法,而注册并实现了这个监听器的类其覆盖的监听器的方法体才是真正当程序执行到这里的时候会执行的代码。(一个是决定什么时间去做,一个是当做的时候我要怎么做),就比如上面的AsyncHttpResponseHandler类其中就定义了两个abstract方法onSuccess()和onFailure(),并且在字节的类里面就规定了,什么时候会去调用这两个方法,因此当我们继承这个类的时候,我们子类其实就相当于拥有了这个功能,我们只需要override这两个方法,那么AsyncHttpResponseHandler就会在适当的时候去调用这两个方法,进而进入并执行我们覆写的方法。

6.什么时候回调用到接口的方法呢?怎么使用接口呢?

两种方式:

其一:定义一个类将一些需要其子类实现的方法定义成interface里面的方法,或者定义成abstract方法,并且定义出调用这些方法的规则(主要是何时进行调用),那么其子类或者实现了这个内部接口的类,就会在此规则下执行其覆盖的方法,

其二:直接定义出一个接口,并在其他的类里面的适当的位置进行调用这个接口里面的abstract方法,因为没有方法体,会自然而然的进入其实现类里面执行其覆盖的方法。

 

7.在同城景点(viewspot)的模块中,我们可以看到网络请求的框架里面有一个封装请求参数的类(BaseTravelRequestParams)此类是旅行箱APP进行网络请求封装网络请求参数的基类,因此其不涉及具体的业务数据,仅仅封装了所有的网络请求参数类都必修要有的一些信息(所有的具体业务相关的请求参数类都必须继承这个类比如你的景点详情页面的TCViewSpotDetailReq),比如编码信息:

//在请求参数中添加编码信息

private void encodeRequestParams(RequestParams params)

{ long current = System.currentTimeMillis();

//添加用户ID

String uid = Code.REQUEST_UID;

params.put("uid", uid);

//添加时间戳

String ts = String.valueOf(current);

params.put("ts", ts);

//添加加密信息

String sig = Config.toMd5(uid+ ":::" + Code.REQUEST_PASSWORD + ":::" + current);

params.put("sig", sig);}

 

这个基类下面有很多的不同的实现类:比如BaseListRequestParams类(进行分页请求的基类,封装了页码,每页数量等参数信息)而其下面又有其他的类我们就不关心了,我们看这个结构主要是为了要分清楚:当我们需要进行网络请求的时候,我们到底需要继承哪一级别的网络请求参数类,这很重要,因为这关系着业务的实现是否有误,并且可以学习如何构建继承体系

 

当网络请求返回数据的时候,会自动调用(前面解释过了为什么自动)AsyncHttpHandlerProxy类的onSuccess()方法,在这个方法里面判断返回的数据是否为空,是否有其他情况,然后可能需要调用DefaultJsonParserProxy来先进行预处理,其实也没什么处理的(自己看)最后调用监听器的onRequestSuccess()方法,


旅行箱的网络请求有一个继承体系:就是封装网络请求参数的体系,最顶层的BaseRequestParams只是用来确定我们使用的loopj框架进行网络请求的时候,所必须的东西(一个是URL,一个是RequestParams),而我们这个体系所做的就是将这两个东西确定出来(不同的具体业务对应不同的URL、和RequestParams)

因为URL是个整体并且可以由具体的业务具体确定,所以直接在最底层的Request里面唯一确定,而RequestParams需要层层封装,在不同的层里面需要添加不同的信息(业务相关层:具体业务参数、请求参数基层实现层:添加加密信息,用户信息等),所以需要从上往下层层分封装实现

如何层层封装呢?(方法可以在基层实现层确定返回的RequestParams对象,并且创建一个抽象方法,让子类进行实现以便于子类项对象中添加参数,然后层层上传封装,最后调用基类实现类的添加加密信息、用户信息等方法,就可得到完整的RequestParams(请求参数)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值