当前位置: 首页 > 工具软件 > OkHttpUtils > 使用案例 >

okhttputils java_超简单的okHttpUtils封装(下)

茅曾琪
2023-12-01

前言:

上一篇我们讲到了基本的Okhttp的封装,只需要我们在代码种调用okHttpUtils.getInstance().GET(url, MyCallBack),一句话完事,而且还是链式的,只需要在MyCallBack中处理返回的Response即可,是不是感觉很爽,不要着急,接下来会让你更爽,请自行准备纸巾,条件允许的话也可以为你的宝贝充上气。没有看过上篇文章的,最好看一下,点击即可跳转: 超简单的okhttp封装工具类(上)。

好了,废话不多说,进入正题,本篇主要思想是,通过上篇的封装,联网成功后,返回的是Response对象,我们平时联网需要的结果是一个JavaBean或者一个集合,泛型为JavaBean。那么,接下来就是实现直接返回带泛型的集合,而不是还需要我们处理的Response。

MyCallBack接口的改写

首先,在MyCallBack后面加上泛型,到时候需要实例化这个callback时候,自然的把我们需要转换成的JavaBean以泛型的形式传递过去。

本篇采用Gson进行Response的json转换,所以需要根据泛型获取Type对象。获取方法如下:

//根据T获取Type

static Type getSuperclassTypeParameter(Class> subclass)

{

Type superclass = subclass.getGenericSuperclass();

if (superclass instanceof Class)

{

throw new RuntimeException("Missing type parameter.");

}

ParameterizedType parameterized = (ParameterizedType) superclass;

return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);

}

1

2

3

4

5

6

7

8

9

10

11

我们原来定义的MyCallBack为接口,此时需要改写成抽象类,因为要用到构造方法进行构造Type对象。具体代码如下:

public abstract class MyCallBack {

public Type mType;

static Type getSuperclassTypeParameter(Class> subclass)

{

Type superclass = subclass.getGenericSuperclass();

if (superclass instanceof Class)

{

throw new RuntimeException("Missing type parameter.");

}

ParameterizedType parameterized = (ParameterizedType) superclass;

return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);

}

public MyCallBack() {

mType = getSuperclassTypeParameter(getClass());

}

public abstract void onLoadingBefore(Request request);

//第二个参数为传入的泛型,也就是说返回的结果直接就是我们需要的类型

public abstract void onSuccess(Response response, T result);

public abstract void onFailure(Request request, Exception e);

public abstract void onError(Response response);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

OkHttpUtils工具类的改写

我们主要是改写Response返回的地方,也就是联网逻辑这一块,即requestNetWork()方法。具体请看代码实现,注释很清晰。

private void requestNetWork(Request request, MyCallBack callBack) {

/**

* 处理连网逻辑,此处只处理异步操作enqueue

*/

callBack.onLoadingBefore(request);

mOkHttpClient.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Call call, IOException e) {

mHandler.post(() -> callBack.onFailure(request, e));

}

@Override

public void onResponse(Call call, Response response) throws IOException {

if (response.isSuccessful()) {

String resultStr = response.body().string();

if (callBack.mType == String.class) {

// 如果想要返回字符串 直接返回就行

mHandler.post(() -> callBack.onSuccess(response, resultStr));

} else {

// 需要返回解析好的javaBean集合

try {

// 此处暂时写成object,使用时返回具体的带泛型的集合

Object obj = mGson.fromJson(resultStr, callBack.mType);

mHandler.post(() -> callBack.onSuccess(response, obj));

} catch (Exception e) {

// 解析错误时

mHandler.post(() -> callBack.onError(response));

}

}

} else {

mHandler.post(() -> callBack.onError(response));

}

}

});

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

界面联网具体操作

具体使用方法如下:在Fragment的OnCreatView方法中写的逻辑,根据需求自己选择在哪里联网,此处只是测试,不建议在这个方法中处理。会阻塞界面显示。

private String url = "http://222.133.11.150:8402/EnvService/Version/CheckVersion?imei=860806029044186&version=111";

@Nullable

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

OkHttpUtils.getInstance().Get(url, new MyCallBack() {

@Override

public void onLoadingBefore(Request request) {

}

@Override

public void onSuccess(Response response, ceshiBean result) {

System.out.println("-----" + result.getStrApkUrl());

}

@Override

public void onFailure(Request request, Exception e) {

}

@Override

public void onError(Response response) {

}

});

return inflater.inflate(R.layout.fragment_home,container,false);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

ceshiBean的代码

这是我们根据接口写的javaBean对象

public class ceshiBean {

/**

* StrApkUrl : http://222.133.11.150:8402/EnvService/versioninfo/EnvDS_DZ.apk

* StrUpdateDate : 2017.4.18

* StrUpdateFlag : 0

* StrUpdateLog :

1.城市空气模块,新增加乡镇站、边界站、农村站、交通站。

* StrVersionCode : 110

* StrVersionName : 1.1.0

*/

private String StrApkUrl;

private String StrUpdateDate;

private String StrUpdateFlag;

private String StrUpdateLog;

private String StrVersionCode;

private String StrVersionName;

public String getStrApkUrl() {

return StrApkUrl;

}

public void setStrApkUrl(String StrApkUrl) {

this.StrApkUrl = StrApkUrl;

}

public String getStrUpdateDate() {

return StrUpdateDate;

}

public void setStrUpdateDate(String StrUpdateDate) {

this.StrUpdateDate = StrUpdateDate;

}

public String getStrUpdateFlag() {

return StrUpdateFlag;

}

public void setStrUpdateFlag(String StrUpdateFlag) {

this.StrUpdateFlag = StrUpdateFlag;

}

public String getStrUpdateLog() {

return StrUpdateLog;

}

public void setStrUpdateLog(String StrUpdateLog) {

this.StrUpdateLog = StrUpdateLog;

}

public String getStrVersionCode() {

return StrVersionCode;

}

public void setStrVersionCode(String StrVersionCode) {

this.StrVersionCode = StrVersionCode;

}

public String getStrVersionName() {

return StrVersionName;

}

public void setStrVersionName(String StrVersionName) {

this.StrVersionName = StrVersionName;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

总结

到此为止,已经实现了简化逻辑,只需要调用方法时候传入泛型javaBean即可,就能直接获取数据了。

可能有的小伙伴会说,这只是单个javaBean对象的解析,如果我们接口返回的是好对个javaBean的集合,怎么办,so easy,只需要把泛型写成List的形式就好了,直接给你返回一个集合数据集,太爽了。

当然,还有更方便的写法,你可以再次自定义一个具体的CallBack继承MyCallBack,实现里面的方法,在联网开始前显示加载对话框,解析结束隐藏对话框,处理相应的逻辑。那么在前台界面只需要处理你自己的数据就可以了。

声明:本文实现思路是参考IVan的封装思路,只做学习用途。

OkHttpUtils改进后的源码

public class OkHttpUtils {

/**

* 网络访问要求singleton

*/

private static OkHttpUtils instance;

// 必须要用的okhttpclient实例,在构造器中实例化保证单一实例

private OkHttpClient mOkHttpClient;

public static final MediaType JSON = MediaType.

parse("application/json; charset=utf-8");

private Handler mHandler;

private Gson mGson;

private OkHttpUtils() {

/**

* okHttp3中超时方法移植到Builder中

*/

mOkHttpClient = (new OkHttpClient()).newBuilder()

.connectTimeout(10, TimeUnit.SECONDS)

.readTimeout(10, TimeUnit.SECONDS)

.writeTimeout(30, TimeUnit.SECONDS)

.build();

mHandler = new Handler(Looper.getMainLooper());

mGson = new Gson();

}

public static OkHttpUtils getInstance() {

if (instance == null) {

synchronized (OkHttpUtils.class) {

if (instance == null) {

instance = new OkHttpUtils();

}

}

}

return instance;

}

/**

* 对外提供的Get方法访问

*@param url

*@param callBack

*/

public void Get(String url, MyCallBack callBack) {

/**

* 通过url和GET方式构建Request

*/

Request request = bulidRequestForGet(url);

/**

* 请求网络的逻辑

*/

requestNetWork(request, callBack);

}

/**

* 对外提供的Post方法访问

*@param url

*@param parms: 提交内容为表单数据

*@param callBack

*/

public void PostWithFormData(String url, Map parms, MyCallBack callBack) {

/**

* 通过url和POST方式构建Request

*/

Request request = bulidRequestForPostByForm(url, parms);

/**

* 请求网络的逻辑

*/

requestNetWork(request, callBack);

}

/**

* 对外提供的Post方法访问

*@param url

*@param json: 提交内容为json数据

*@param callBack

*/

public void PostWithJson(String url, String json, MyCallBack callBack) {

/**

* 通过url和POST方式构建Request

*/

Request request = bulidRequestForPostByJson(url, json);

/**

* 请求网络的逻辑

*/

requestNetWork(request, callBack);

}

/**

* POST方式构建Request {json}

*@param url

*@param json

*@return

*/

private Request bulidRequestForPostByJson(String url, String json) {

RequestBody body = RequestBody.create(JSON, json);

return new Request.Builder()

.url(url)

.post(body)

.build();

}

/**

* POST方式构建Request {Form}

*@param url

*@param parms

*@return

*/

private Request bulidRequestForPostByForm(String url, Map parms) {

FormBody.Builder builder = new FormBody.Builder();

if (parms != null) {

for (Map.Entry entry :

parms.entrySet()) {

builder.add(entry.getKey(), entry.getValue());

}

}

FormBody body = builder.build();

return new Request.Builder()

.url(url)

.post(body)

.build();

}

/**

* GET方式构建Request

*@param url

*@return

*/

private Request bulidRequestForGet(String url) {

return new Request.Builder()

.url(url)

.get()

.build();

}

private void requestNetWork(Request request, MyCallBack callBack) {

/**

* 处理连网逻辑,此处只处理异步操作enqueue

*/

callBack.onLoadingBefore(request);

mOkHttpClient.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Call call, IOException e) {

mHandler.post(() -> callBack.onFailure(request, e));

}

@Override

public void onResponse(Call call, Response response) throws IOException {

if (response.isSuccessful()) {

String resultStr = response.body().string();

if (callBack.mType == String.class) {

// 如果想要返回字符串 直接返回就行

mHandler.post(() -> callBack.onSuccess(response, resultStr));

} else {

// 需要返回解析好的javaBean集合

try {

// 此处暂时写成object,使用时返回具体的带泛型的集合

Object obj = mGson.fromJson(resultStr, callBack.mType);

mHandler.post(() -> callBack.onSuccess(response, obj));

} catch (Exception e) {

// 解析错误时

mHandler.post(() -> callBack.onError(response));

}

}

} else {

mHandler.post(() -> callBack.onError(response));

}

}

});

}

}

 类似资料: