概述
和以往的套路一样,先导入一个依赖包:
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
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,你们可以根据自己的需求在我封装的网络请求类里面,把相关参数放在请求头里面即可):
OkhttpUtils.getInstance().getJson(str, new OkhttpUtils.HttpCallBack() {
@Override
public void onSusscess(String data) {
}
@Override
public void onError(String meg) {
}
});
下面是上传照片、图片文件,多张图片带参数的例子,套路都差不多,多了就找一个方法管理就行了,我就把完整的代码展示出来了。
我封装Okhttp用的是单例模式,单例模式的特性就是只允许创建一个实例,能减少内存的消耗,代码里面也有注释,请大家好好看一下吧。
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 Okhttp封装get,post请求以及上传图片带参数,无参详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复