okhttp3极简封装

        去年在使用okhttp3的时候封装了一个库,准确来说,是想封装成一个公共库,结果还没完全写好的时候,新项目突然而至,于是直接使用了!结果......额.....虽然接近了我的效果,但还是不够好,这次趁着新项目还不是很急的时候,又重新修改了一次,删掉很多多余的代码,换了一些实现方法,对比之前可以说是精简好多,因此记录下来,慢慢改进。

        一切以需求出发!

        为什么要封装?okhttp只是帮我们做了网络请求的事情,然后把请求结果给我们,但是我们在使用的时候,并不是很方便,也不是很人性化,一句话说就是我们需要一层按照我们思维习惯来的一层与okhttp相连接,才能更好的使用okhttp。需求是什么?我的需求很简单,在使用的地方尽量做到最简。什么样个简法?在使用的地方以最少的代码完成一次网络请求和得到我们想要的结果,说那么多干嘛,上图

这就是要完成一次网络请求的全部代码。是不是够简!下面来解释一下

        首先什么是LoginAction?它是我们这次请求用到的参数实体,后面会细讲。先实例化一个参数实体,然后调用HttpManager的方法doActionPost并传过去,同时可传当前上下文环境,传即会弹出dialog,传null则不弹。new一个callback实例,并传入需要的返回的泛型类,然后实现两个抽象的回调方法即可,其中onResult方法会返回我们需要的实体,可直接使用。

        这里开始要分两步了,第一LoginAction有什么玄机?第二doActionPost方法又做了什么?

 

这个就是LoginAction的全部内容,它继承了GAction,GAction又是什么鬼?

 

好像没什么啊,就两个抽象方法。好先晾一边(不过也做了注释...)

前面我说了,这是一个参数实体,那么它必然就是我们这次请求的参数了,参数还有这样写的?是的,为了方便。这里我们看到有两个参数name和password,我们假设这是用于登录的参数实体,这两个就是参数用户名跟密码。等等我又发现了什么?这两个参数顶部好像有个注解呢~是的,因为我们的参数是有可能要经过处理,总不能就这样扔上去吧?没错就是做加密用的,后面会讲到。

getActionApi()方法返回一个字符串,也就是这个请求的接口。getResultType()会返回一个Type,表示这次请求完成后处理的结果,把它给我处理成这个类。好,参数实体类算完了。下面看doActionPost做了什么(真是满肚子疑问)

 

这个是HttpManager类,使用单例模式,初始化就没什么好讲的了,就是初始化OkHttpClient和handler之类的我们要使用的对象。下面看doActionPost方法,首先看到两个判断,而这两个判断正是前面的getActionApi()和getResultType()提供的值,一个是接口,一个是类型,只有这两个有值了才进行下一步,其中会他获取到的Type设给callback,用作解析数据。然后重要的一环是实例化okhttp的请求参数Request,怎么实例化呢,第一个参数url,也就是baseUrl和参数实体提供的接口组成;第二个是什么?我们进去看

 

看注释可能就知道,是将参数实体转换为okhttp要用的参数实体。这里使用Java的反射机制,取到我们定义的name和password,当然我现在只是做了string的参数处理。拿到这两个参数之后,还要判断是否需要加密,如果需要则加密。代码很简单,相信一看就懂。然后把这两个参数放进RequestBody返回给Request。这里okhttp的参数已经完成,接下来就拿去请求就行

        CallmCall=okBuilder.build().newCall(request);
        callBack.setmCall(mCall);
        mCall.enqueue(callBack);

请求结果在哪?callback里面,好我们看下callback做了啥。

 


callback需要实现Callback接口,这是okhttp的结果回调,我们在回调方法里做我们需要的处理,再将结果回调给是使用者,也就是前面实例化callback的地方。

然后我们定义两个抽象方法,可根据需要定义更多。这两个便是回调方法了,需要在使用的地方实现,我们把结果返回给它就行。

 


这两个就是实现okhttp的Callback接口要实现的方法。我们在onResponse开始,这里是这次请求的回调,我们先判断返回码,如果是200,证明这次请求成功了,如果不是,则失败,可能是404可能是500等等,我们根据我们的需要做我们的业务即可,当然这里我还没做。请求成功之后,我们能直接拿到返回的string原始数据,然后第一步我们就是直接将它转成实体类,怎么转?其实很简单,用gson的fromJson方法,直接就能得到一个你定义好的跟返回结果一样结构的实体类了。这里要注意的是这个方法有两个参数,第一个是json字符串,第二个是这个实体类的类型,这个类型那里来,就是在参数实体那里指定的也就是getResultType()方法返回的。而BaseResultEntity<T>中的T作为泛型要与getResultType()方法中的保持一致,这样才能成功解析出来,否则就走catch方法了。得到解析好的实体类之后,我们还要做判断,为什么?因为我们所有接口返回的数据格式都是一致的,比如


如果不是这样的?呵呵......那就太不规范了,拉出去打

言归正传,如果code是1则表示这次请求以及这次操作是符合我们预期结果,然后我们调用抽象方法onResult(Tresult)并把BaseResultEntity中的泛型数据给它,也就是我们最终想要的数据如上图中的data实体了。否则就走onError方法,然后把描述传回去,这个根据我们的需要定义就行...

 

还有一个地方就是dialog的处理

 

当有上下文环境传过来时,弹出dialog,同时,点返回键取消时,要把当前call对象cancel掉,这个Call是前面传过来的,同样的,如果是这次Call执行完毕,也要把dialog给cancel掉,这样就~~~行了。

终于讲完~

但是~~~但是来了...

这只是做了一个很简单的post请求啊,get呢、图片上传下载呢个哥~~好吧革命尚未完成,同志还需努力

存在的问题

前面讲了那么多,终于可以以最简的方式(目前我所知道的)完成一次网络请求了。那么久万事大吉了?肯定不是

问题一、扩展问题,如果真要封装,那么很多东西就要以配置化的形式出现,比如OkHttpClient,比如baseUrl等等,这些都还没做。

问题二、性能与内存泄露,可以看到callback中承载了很多事情,对结果的处理、对dialog的处理等等,而已引用了handler、Call等对象,会不会出现内存泄露?由于我对这方面也不是很了解,因此暂时还不知道,只是以现在的手机使用来看,没啥问题,还挺快的~~这部分还要留心观察。

对于结果方法,其实还有个情况我还没做的,就是对于很多系统来说都有的token,如果token失效,会做一个统一的处理,比如跳到登录页面,这个还得加上。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值