我是靠谱客的博主 背后钢笔,这篇文章主要介绍Android Okhttp封装get,post请求以及上传图片带参数,无参详解,现在分享给大家,希望可以做个参考。

和以往的套路一样,先导入一个依赖包:
implementation 'com.squareup.okhttp3:okhttp:3.9.0'

    我封装的是一个Okhttp工具类,有get请求,有post请求,还有上传照片文件功能,我先一步一步的解析这几个方法,最下面是一个封装好的工具类,复制粘贴即可使用:

Okhttp优点:

    1. 支持 SPDY ,允许连接同一主机的所有请求分享一个socket。

    2. 如果SPDY不可用,会使用连接池减少请求延迟。

    3. 使用GZIP压缩下载内容,且压缩操作对用户是透明的。

    4. 利用响应缓存来避免重复的网络请求。

Okhttp特点:

    1. 当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。

    2. 如果你的服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。 

    3. OKHttp利用TLS的特性初始化新的连接,如果握手失败便退回到SSLV3。

    4. OKHttp的使用很简单。其2.0API拥有流畅的构建器和稳定性。它支持同步阻塞请求和异步回调请求。

    5. 你可以试试OKHttp而不重写网络代码。okhttp-urlconnection模块实现了都很熟悉的Java.net.HttpURLConnection的API,okhttp-apache模块实现了Apache的HttpClient的API。

    6. OKHttp支持android2.3以上,Java支持最低版本1.7。

下面给大家写一个简单好用的okhttp网络请求工具类,分为两个请求方式(get和post请求),简单说一下get和post的区别:

1.当发送数据的时候,get的url是有长度限制的(最大长度是2048),而post是没有限制   

2.get的安全性较差,post请求比get请求更安全get请求会把参数保留在浏览网页中,而post不会保存到浏览器的历史或服务器日志中  

3.直接请求数据就用get , 如果需要给后台传数据那就用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
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
import android.os.Handler; import android.os.Looper; import android.util.Log; import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * Created by Administrator on 2019/7/18. */ public class OkhttpUtils { private static final String TAG="OkhttpUtils"; private OkHttpClient mClient; private static volatile OkhttpUtils mOkUtils;//防止多个线程同时访问 public static final int TIMEOUT = 1000 * 5; private Handler handler = new Handler(Looper.getMainLooper()); //json请求 public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); //使用构造方法初始化 public OkhttpUtils(){ mClient=new OkHttpClient(); } //使用单利模式,通过获取的方式拿到对象(还为了优化内存,单利模式只可创建一次)z public static OkhttpUtils getInstance(){ if(mOkUtils==null){ synchronized (OkhttpUtils.class){ if(mOkUtils==null){ mOkUtils=new OkhttpUtils(); mOkUtils.initUtils(); } } } return mOkUtils; } /** * 应用拦截器 */ Interceptor appInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); String s = url.url().toString(); //———请求之前—– Log.d(TAG,"app interceptor:begin"); Response response = chain.proceed(request); Log.d(TAG,"app interceptor:end"); //———请求之后———— return response; } }; private void initUtils(){ mClient.newBuilder() .connectTimeout(TIMEOUT, TimeUnit.SECONDS) .writeTimeout(TIMEOUT, TimeUnit.SECONDS) .readTimeout(TIMEOUT, TimeUnit.SECONDS) //拦截器 .addInterceptor(appInterceptor) .build(); } /** * okhttp get 请求 * **/ public void getJson(String url,final HttpCallBack callBack){ Request request=new Request.Builder() .url(url) .get() .build(); mClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (e instanceof SocketTimeoutException) { OnError(callBack, "连接超时"); } else if (e instanceof ConnectException) { OnError(callBack, "连接服务器失败"); } else if (e instanceof UnknownHostException) { OnError(callBack, "网络异常"); } else { OnError(callBack, "未知错误"); } } @Override public void onResponse(Call call, Response response) throws IOException { String string = response.body().string(); onSuccess(callBack,string); } }); } /** * okhttp post请求 * */ public void postJson(String url, String json, final HttpCallBack callBack){ RequestBody requestBody=RequestBody.create(JSON,json); Request request=null; request=new Request.Builder() .url(url) .post(requestBody) .build(); mClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (e instanceof SocketTimeoutException) { OnError(callBack, "连接超时"); } else if (e instanceof ConnectException) { OnError(callBack, "连接服务器失败"); } else if (e instanceof UnknownHostException) { OnError(callBack, "网络异常"); } else { OnError(callBack, "未知错误"); } } @Override public void onResponse(Call call, Response response) throws IOException { String string = response.body().string(); onSuccess(callBack,string); } }); } public void onSuccess(final HttpCallBack callBack, final String data) { if (callBack != null) { handler.post(new Runnable() { @Override public void run() {//在主线程操作 callBack.onSusscess(data); } }); } } public void OnError(final HttpCallBack callBack, final String msg) { if (callBack != null) { handler.post(new Runnable() { @Override public void run() { callBack.onError(msg); } }); } } public static abstract class HttpCallBack { //成功回调 public abstract void onSusscess(String data); //失败 public abstract void onError(String meg); } }

为了一下初学的萌生,调用方法也推荐一下,用下面的方式调用(下面只粘贴了get请求,post请求的话就把get换成post,即可,这工具类都可以更改,有的公司要session ,有的公司需要cookie,你们可以根据自己的需求在我封装的网络请求类里面,把相关参数放在请求头里面即可):

复制代码
1
2
3
4
5
6
7
8
9
OkhttpUtils.getInstance().getJson(str, new OkhttpUtils.HttpCallBack() { @Override public void onSusscess(String data) { } @Override public void onError(String meg) { } });

下面是上传照片、图片文件,多张图片带参数的例子,套路都差不多,多了就找一个方法管理就行了,我就把完整的代码展示出来了。

我封装Okhttp用的是单例模式,单例模式的特性就是只允许创建一个实例,能减少内存的消耗,代码里面也有注释,请大家好好看一下吧。

复制代码
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
import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.util.Log; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; /** * OKHttp3上传工具类 * */ public class OkhttpUtils { private Context ctx; private static OkHttpClient ok = null; private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); private Map<String, String> map = new HashMap<String, String>();//存放 private List<String> list = new ArrayList<String>(); private static File file; private static String imgpath; private static String imageName; private OkhttpUtils() { } ; /* *单例获取 * */ public static OkHttpClient getInstance() { if (ok == null) { synchronized (OkhttpUtils.class) { if (ok == null) ok = new OkHttpClient(); } } return ok; } public static void getString(String url, Callback callback) { Request request = new Request.Builder() .url(url) .build(); Call call = getInstance().newCall(request); call.enqueue(callback); } /* * 键值对上传数据 * */ public static void postString(String url, Map<String, String> map, Callback callback) { FormBody.Builder builder = new FormBody.Builder(); //遍历map中所有的参数到builder for (String key : map.keySet()) { builder.add(key, map.get(key)); Log.e("", "key: " + key + " map.get: " + map.get(key)); } Request request = new Request.Builder() .url(url) .post(builder.build()) .build(); Call call = getInstance().newCall(request); call.enqueue(callback); } /* * 上传一张图片带参数 * */ public static void UploadFileCS(String url, String key1, String path, Map<String, String> map, Callback callback) { // path.lastIndexOf是找到uri里面最后一个"你想找的东西"的位置,所以就是截取最后一个"/"和最后一个"."之间的东西, String imagpath = path.substring(0, path.lastIndexOf("/")); String imgName[] = path.split("/"); for (int i = 0; i < imgName.length; i++) { if (i == imgName.length - 1) { String name = imgName[i]; file = new File(imagpath, name); } } MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); RequestBody fileBody = RequestBody.create(MEDIA_TYPE_PNG, file); //遍历map中所有的参数到builder for (String key : map.keySet()) { builder.addFormDataPart(key, map.get(key)); } //讲文件添加到builder中 builder.addFormDataPart(key1, file.getName(), fileBody); //创建请求体 RequestBody requestBody = builder.build(); Request request = new Request.Builder().url(url).post(requestBody).build(); Call call = getInstance().newCall(request); call.enqueue(callback); } /* *上传多个图片文件 * */ @SuppressWarnings("unused") public static void UploadFileMore(String url, List<String> paths, Callback callback) { if (paths != null) { //创建文件集合 List<File> list = new ArrayList<File>(); //遍历整个图片地址 for (String str : paths) { //截取图片地址:/storage/emulated/0 imgpath = str.substring(0, str.lastIndexOf("/")); //将图片路径分解成String数组 String[] imgName = str.split("/"); for (int i = 0; i < imgName.length; i++) { if (i == imgName.length - 1) { imageName = imgName[i];//获取图片名称 File file = new File(imgpath, imageName); list.add(file); } } } MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM);//设置表单类型 //遍历图片文件 for (File file : list) { if (file != null) { builder.addFormDataPart("acrd", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } } //构建请求体 MultipartBody requestBody = builder.build(); Request request = new Request.Builder().url(url).post(requestBody).build(); Call call = getInstance().newCall(request); call.enqueue(callback); } } /* * 上传多张图片带参数 * */ @SuppressWarnings("unused") public static void UploadFileSCMore(String url, String value, List<String> paths, Map<String, String> map, Callback callback) { if (paths != null && map != null) { //创建文件集合 List<File> list = new ArrayList<File>(); //遍历整个图片地址 for (String str : paths) { //截取图片地址:/storage/emulated/0 imgpath = str.substring(0, str.lastIndexOf("/")); //将图片路径分解成String数组 String[] imgName = str.split("/"); for (int i = 0; i < imgName.length; i++) { if (i == imgName.length - 1) { imageName = imgName[i];//获取图片名称 File file = new File(imgpath, imageName); list.add(file); } } } MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM);//设置表单类型 //遍历图片文件 for (File file : list) { if (file != null) { builder.addFormDataPart(value, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)); } } //遍历map中所有的参数到builder for (String key : map.keySet()) { builder.addFormDataPart(key, map.get(key)); } RequestBody requestBody = builder.build(); Request request = new Request.Builder().url(url).post(requestBody).build(); Call call = getInstance().newCall(request); call.enqueue(callback); } } }

 

 

 

 

 

 


 

最后

以上就是背后钢笔最近收集整理的关于Android Okhttp封装get,post请求以及上传图片带参数,无参详解的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(93)

评论列表共有 0 条评论

立即
投稿
返回
顶部