Android -- Simple use and packaging of OkHttp

Encapsulation of OkHttp

Since it is packaged, we can combine OKHttp and Gson, then we add the following dependencies to the gradle file

1

2

3

compile "com.squareup.okhttp:okhttp:2.4.0"

compile 'com.squareup.okio:okio:1.5.0'

compile "com.google.code.gson:gson:2.8.0"

  ①CallBack creation  

  First of all, we know that when the interface request succeeds or fails, we need to notify the user of this information, then we need to create an abstract class RequestCallBack, the methods before the request, success, failure, and after the request, create OnBefore(), OnAfter(), OnError(), OnResponse() correspond

  

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

/**

 * 在请求之前的方法,一般用于加载框展示

 *

 * @param request

 */

public void onBefore(Request request) {

}

/**

 * 在请求之后的方法,一般用于加载框隐藏

 */

public void onAfter() {

}

/**

 * 请求失败的时候

 *

 * @param request

 * @param e

 */

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

/**

 *

 * @param response

 */

public abstract void onResponse(T response);

 Since the data we want is not necessarily every time, so here we use <T> to receive the data format we want to pretend, and get the desired data type (usually Bean, List) through reflection, so RequestCallBack The overall code is as follows:

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

package com.qianmo.httprequest.http;

import com.google.gson.internal.$Gson$Types;

import com.squareup.okhttp.Request;

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.Type;

/**

 * Created by wangjitao on 15/10/16.

 * 抽象类,用于请求成功后的回调

 */

public abstract class ResultCallback<T> {

    //这是请求数据的返回类型,包含常见的(Bean,List等)

    Type mType;

    public ResultCallback() {

        mType = getSuperclassTypeParameter(getClass());

    }

    /**

     * 通过反射想要的返回类型

     *

     * @param subclass

     * @return

     */

    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]);

    }

    /**

     * 在请求之前的方法,一般用于加载框展示

     *

     * @param request

     */

    public void onBefore(Request request) {

    }

    /**

     * 在请求之后的方法,一般用于加载框隐藏

     */

    public void onAfter() {

    }

    /**

     * 请求失败的时候

     *

     * @param request

     * @param e

     */

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

    /**

     *

     * @param response

     */

    public abstract void onResponse(T response);

}

  ② Simple encapsulation of Get and Post methods 

  First of all, we create a OkHttpClientManager class. Since it is a management class, we start with a singleton and a static object.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

private static OkHttpClientManager mInstance;

 public static OkHttpClientManager getInstance() {

       if (mInstance == null){

           synchronized (OkHttpClientManager.class) {

               if (mInstance == null) {

                   mInstance = new OkHttpClientManager();

               }

           }

       }

       return mInstance;

   }

 When creating the Manager object, we need to configure some parameters of OkHttp. By the way, since our asynchronous get and post methods run in sub-threads, here we add the distributed Handler mDelivery;, rewritten The construction method of OkHttpClientManager is as follows:

1

2

3

4

5

6

7

8

9

10

private OkHttpClientManager() {

       mOkHttpClient = new OkHttpClient();

       mOkHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);

       mOkHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);

       mOkHttpClient.setReadTimeout(30, TimeUnit.SECONDS);

       //cookie enabled

       mOkHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER));

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

       mGson = new Gson();

   }

  The previous external call object is encapsulated. Here we start to encapsulate the Get or Post method. Let me take the Post method as an example. First, analyze that the post method will have several parameters, the first parameter is url, the second parameter is params, Parameter three Callback (and our above RequestCallBack) parameter four flag (used to cancel the request operation, can be empty), the basic code is as follows:

1

2

3

4

5

6

7

8

9

10

/**

        * 通用基础的异步的post请求

        * @param url

        * @param callback

        * @param tag

        */

       public void postAsyn(String url, Param[] params, final ResultCallback callback, Object tag) {

           Request request = buildPostFormRequest(url, params, tag);

           deliveryResult(callback, request);

       }

  Then let's take a look at what the deliveryResult method does

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

/**

    * 请求回调处理方法并传递返回值

    * @param callback Map类型请求参数

    * @param request Request请求

    */

   private void deliveryResult(ResultCallback callback, Request request) {

       if (callback == null)

           callback = DEFAULT_RESULT_CALLBACK;

       final ResultCallback resCallBack = callback;

       //UI thread

       callback.onBefore(request);

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

           @Override

           public void onFailure(final Request request, final IOException e) {

               sendFailedStringCallback(request, e, resCallBack);

           }

           @Override

           public void onResponse(final Response response) {

               try {

                   final String responseMessage=response.message();

                   final String responseBody = response.body().string();

                   if(response.code()==200){

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

                           sendSuccessResultCallback(responseBody, resCallBack);

                       else {

                           Object o = mGson.fromJson(responseBody, resCallBack.mType);

                           sendSuccessResultCallback(o, resCallBack);

                       }

                   }else{

                       Exception exception=new Exception(response.code()+":"+responseMessage);

                       sendFailedStringCallback(response.request(), exception, resCallBack);

                   }

               catch (IOException e) {

                   sendFailedStringCallback(response.request(), e, resCallBack);

               catch (com.google.gson.JsonParseException e) { //Json解析的错误

                   sendFailedStringCallback(response.request(), e, resCallBack);

               }

           }

       });

   }

  可以看到,这个方法主要是发出请求并对请求后的数据开始回调,这样我们就基本上封装好了一个post方法了  ,把代码这一部分的代码贴出来看看

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

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

public class OkHttpClientManager {

    private static final String TAG = "com.qianmo.httprequest.http.OkHttpClientManager";

    private static OkHttpClientManager mInstance;

    //默认的请求回调类

    private final ResultCallback<String> DEFAULT_RESULT_CALLBACK = new ResultCallback<String>(){

        @Override

        public void onError(Request request, Exception e) {}

        @Override

        public void onResponse(String response) {}

    };

    private OkHttpClient mOkHttpClient;

    private Handler mDelivery;

    private Gson mGson;

    private GetDelegate mGetDelegate = new GetDelegate();

    private PostDelegate mPostDelegate = new PostDelegate();

    private DownloadDelegate mDownloadDelegate = new DownloadDelegate();

    private OkHttpClientManager() {

        mOkHttpClient = new OkHttpClient();

        mOkHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);

        mOkHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);

        mOkHttpClient.setReadTimeout(30, TimeUnit.SECONDS);

        //cookie enabled

        mOkHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER));

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

        mGson = new Gson();

    }

    public static OkHttpClientManager getInstance() {

        if (mInstance == null){

            synchronized (OkHttpClientManager.class) {

                if (mInstance == null) {

                    mInstance = new OkHttpClientManager();

                }

            }

        }

        return mInstance;

    }

    /**

     * 外部可调用的Post异步请求方法

     * @param url 请求url

     * @param params

     * @param callback 请求完成后回调类

     */

    public static void postAsyn(String url, Map<String, String> params, final ResultCallback callback) {

        getInstance().getPostDelegate().postAsyn(url, params, callback, null);

    }

    /**

         * 异步的post请求

         * @param url

         * @param params

         * @param callback

         * @param tag

         */

        public void postAsyn(String url, Map<String, String> params, final ResultCallback callback, Object tag) {

            Param[] paramsArr = map2Params(params);

            postAsyn(url, paramsArr, callback, tag);

        }

    /**

         * 通用基础的异步的post请求

         * @param url

         * @param callback

         * @param tag

         */

        public void postAsyn(String url, Param[] params, final ResultCallback callback, Object tag) {

            Request request = buildPostFormRequest(url, params, tag);

            deliveryResult(callback, request);

        }

     

    /**

     * 请求回调处理方法并传递返回值

     * @param callback Map类型请求参数

     * @param request Request请求

     */

    private void deliveryResult(ResultCallback callback, Request request) {

        if (callback == null)

            callback = DEFAULT_RESULT_CALLBACK;

        final ResultCallback resCallBack = callback;

        //UI thread

        callback.onBefore(request);

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

            @Override

            public void onFailure(final Request request, final IOException e) {

                sendFailedStringCallback(request, e, resCallBack);

            }

            @Override

            public void onResponse(final Response response) {

                try {

                    final String responseMessage=response.message();

                    final String responseBody = response.body().string();

                    if(response.code()==200){

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

                            sendSuccessResultCallback(responseBody, resCallBack);

                        else {

                            Object o = mGson.fromJson(responseBody, resCallBack.mType);

                            sendSuccessResultCallback(o, resCallBack);

                        }

                    }else{

                        Exception exception=new Exception(response.code()+":"+responseMessage);

                        sendFailedStringCallback(response.request(), exception, resCallBack);

                    }

                catch (IOException e) {

                    sendFailedStringCallback(response.request(), e, resCallBack);

                catch (com.google.gson.JsonParseException e) { //Json解析的错误

                    sendFailedStringCallback(response.request(), e, resCallBack);

                }

            }

        });

    }

     /**

     * 处理请求成功的回调信息方法

     * @param object 服务器响应信息

     * @param callback 回调类

     */

    private void sendSuccessResultCallback(final Object object, final      ResultCallback callback) {

        mDelivery.post(() -> {

            callback.onResponse(object);

            callback.onAfter();

        });

    }

}    

  这样我们就把Post方法封装好了,同理Get方法,ok,现在我们可以来调用调用了,在调用之前我们可以对返回数据格式再来封装封装,一般我们后台返回的数据格式是类似如下:

1

2

3

4

5

{

 "code"200,

  "data": {},

 "message""登录成功"

}

 而data中有可能是对象,也有可能是数组,所以我们用两个类来实现一下

 CommonResultBean

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

package com.qianmo.httprequest.bean;

/**

 * 服务端返回通用接收实体

 * Created by wangjitao on 15/10/30.

 */

public class CommonResultBean<T> {

    private String code;

    private T data;

    private String message;

    public String getCode() {

        return code;

    }

    public void setCode(String code) {

        this.code = code;

    }

    public T getData() {

        return data;

    }

    public void setData(T data) {

        this.data = data;

    }

    public String getMessage() {

        return message;

    }

    public void setMessage(String message) {

        this.message = message;

    }

}

 CommonResultListBean

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

package com.qianmo.httprequest.bean;

import java.util.List;

/**

 * 服务端返回带有List数据的通用接收实体

 * Created by wangjitao on 15/12/1.

 */

public class CommonResultListBean<T> {

    private String code;

    private List<T> data;

    private String message;

    public String getCode() {

        return code;

    }

    public void setCode(String code) {

        this.code = code;

    }

    public List<T> getData() {

        return data;

    }

    public void setData(List<T> data) {

        this.data = data;

    }

    public String getMessage() {

        return message;

    }

    public void setMessage(String message) {

        this.message = message;

    }

}

  ok,现在还是以上面我们登录的接口为例子开始我们的方法调用,返回的数据格式如图所示

  我们创建UserMenu.java类

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

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

package com.qianmo.httprequest.bean;

import java.util.List;

/**

 * Created by wangjitao on 2016/12/21 0021.

 * E-Mail:[email protected]

 * 用户菜单权限按钮

 */

public class UserMenu {

    /**

     * last_login_time : 2016-12-21 15:40:28

     * member_id : 1

     * modules : []

     * phone : 18900532225

     * real_name : 超级管理员

     * role : {"role_id":1,"role_name":"超级管理员"}

     * username : superadmin

     */

    private String last_login_time;

    private int member_id;

    private String phone;

    private String real_name;

    /**

     * role_id : 1

     * role_name : 超级管理员

     */

    private RoleBean role;

    private String username;

    /**

     * module_code : 100

     * module_id : 1

     * module_name : 首页

     * pid : 0

     * type : 1

     * value : P_index

     */

    private List<ModulesBean> modules;

    public String getLast_login_time() {

        return last_login_time;

    }

    public void setLast_login_time(String last_login_time) {

        this.last_login_time = last_login_time;

    }

    public int getMember_id() {

        return member_id;

    }

    public void setMember_id(int member_id) {

        this.member_id = member_id;

    }

    public String getPhone() {

        return phone;

    }

    public void setPhone(String phone) {

        this.phone = phone;

    }

    public String getReal_name() {

        return real_name;

    }

    public void setReal_name(String real_name) {

        this.real_name = real_name;

    }

    public RoleBean getRole() {

        return role;

    }

    public void setRole(RoleBean role) {

        this.role = role;

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public List<ModulesBean> getModules() {

        return modules;

    }

    public void setModules(List<ModulesBean> modules) {

        this.modules = modules;

    }

    public static class RoleBean {

        private int role_id;

        private String role_name;

        public int getRole_id() {

            return role_id;

        }

        public void setRole_id(int role_id) {

            this.role_id = role_id;

        }

        public String getRole_name() {

            return role_name;

        }

        public void setRole_name(String role_name) {

            this.role_name = role_name;

        }

    }

    public static class ModulesBean {

        private String module_code;

        private int module_id;

        private String module_name;

        private int pid;

        private int type;

        private String value;

        public String getModule_code() {

            return module_code;

        }

        public void setModule_code(String module_code) {

            this.module_code = module_code;

        }

        public int getModule_id() {

            return module_id;

        }

        public void setModule_id(int module_id) {

            this.module_id = module_id;

        }

        public String getModule_name() {

            return module_name;

        }

        public void setModule_name(String module_name) {

            this.module_name = module_name;

        }

        public int getPid() {

            return pid;

        }

        public void setPid(int pid) {

            this.pid = pid;

        }

        public int getType() {

            return type;

        }

        public void setType(int type) {

            this.type = type;

        }

        public String getValue() {

            return value;

        }

        public void setValue(String value) {

            this.value = value;

        }

    }

}

  所以MainActivity代码如下:

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

67

68

69

70

71

72

73

74

75

76

77

78

79

package com.qianmo.httprequest;

import android.os.Environment;

import android.os.Handler;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ProgressBar;

import android.widget.TextView;

import com.qianmo.httprequest.bean.CommonResultBean;

import com.qianmo.httprequest.bean.UserMenu;

import com.qianmo.httprequest.http.IRequestCallBack;

import com.qianmo.httprequest.http.IRequestManager;

import com.qianmo.httprequest.http.OkHttpClientManager;

import com.qianmo.httprequest.http.RequestFactory;

import com.qianmo.httprequest.http.ResultCallback;

import com.squareup.okhttp.Call;

import com.squareup.okhttp.Callback;

import com.squareup.okhttp.FormEncodingBuilder;

import com.squareup.okhttp.OkHttpClient;

import com.squareup.okhttp.Request;

import com.squareup.okhttp.RequestBody;

import com.squareup.okhttp.Response;

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

public class MainActivity extends AppCompatActivity implements OnClickListener {

    private Handler handler;

    private TextView tv_message;

    private Button btn_login;

    private ProgressBar progressBar;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        tv_message = (TextView) findViewById(R.id.tv_message);

        btn_login = (Button) findViewById(R.id.btn_login);

        progressBar = (ProgressBar) findViewById(R.id.progressBar);

        handler = new Handler();

        btn_login.setOnClickListener(this);

    }

    @Override

    public void onClick(View view) {

        progressBar.setVisibility(View.VISIBLE);

        String url = "http://192.168.1.123:8081/api/login";

        Map<String, String> params = new HashMap();

        params.put("username""superadmin");

        params.put("pwd""ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413");

        OkHttpClientManager.postAsyn(url, params,

                new ResultCallback<CommonResultBean<UserMenu>>() {

                    @Override

                    public void onError(Request request, Exception e) {

                    }

                    @Override

                    public void onResponse(CommonResultBean<UserMenu> response) {

                        if (response.getData() != null) {

                            UserMenu userMenu = response.getData();

                            tv_message.setText(userMenu.getReal_name());

                            progressBar.setVisibility(View.GONE);

                        }

                    }

                });

    }

}

  这样我们就可以简单的调用了,最后看一下我们的效果:

 See You Next Time···

Guess you like

Origin blog.csdn.net/m0_70748845/article/details/130058102