OkHttp 主要实现功能如下
- 一般的get post请求
- 基于Http的文件上传
- 文件下载
- 加载图片
- 迟滞请求回调。直接返回对象,对象集合,
- 支持session的保持
封装基类如下
package com.liuan.ok_demo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class OkManager {
private OkHttpClient client;
private volatile static OkManager manager;
private static final String TAG = "OkManager";
private Handler handler;
//提交json数据
private static final MediaType JSON = MediaType.parse("application/json:charset=utf-8");
//提交字符串
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");
private OkManager() {
client = new OkHttpClient();
handler = new Handler(Looper.getMainLooper());
}
//采用单例模式获取对象
public static OkManager getInstance() {
OkManager instance = null;
if (manager == null) {
synchronized (OkManager.class) {
instance = new OkManager();
manager = instance;
}
}
return instance;
}
/**
* 同步请求数据 在android 开发中不常用,因为阻塞UI线程
*
* @param url
* @return
*/
public String syncGitByURL(String url) {
Request request = new Request.Builder().url(url).build();
//构建一个request请求
Response response = null;
try {
//同步请求数据
response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 请求指定的url返回的记过是json字符串
*
* @param url
* @param callBack
*/
public void asyncJsonStringByURL(String url, final CallBackString callBack) {
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessJsonStringMethod(response.body().string(), callBack);
}
}
});
}
/**
* 请求返回的结果json 字符串
*
* @param jsonValue
* @param callBack
*/
private void onSuccessJsonStringMethod(final String jsonValue, CallBackString callBack) {
handler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
try {
callBack.onResponse(jsonValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
/**
* 请求返回的结果json 对象
*
* @param jsonValue
* @param callBack
*/
private void onSucessJsonObjectMethod(final String jsonValue, CallBackJsonObject callBack) {
handler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
try {
callBack.onResponse(new JSONObject(jsonValue));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
public void sayncJsonObkectByURL(String url, final CallBackJsonObject callBack) {
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSucessJsonObjectMethod(response.body().string(), callBack);
}
}
});
}
public void asyncGetByteByURL(String url, final CallBackByte callBack) {
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
onSucessByteMethod(response.body().bytes(), callBack);
}
});
}
/**
* 请求返回json对象
*
* @param url
* @param callback
*/
public void asyncJsonObjectByURL(String url, final CallBackJsonObject callback) {
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSucessJsonObjectMethod(response.body().string(), callback);
}
}
});
}
public void asyncGetByteURL(String url, final CallBackByte callBack) {
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSucessByteMethod(response.body().bytes(), callBack);
}
}
});
}
/**
* 采用post提交表单
*
* @param url
* @param params
* @param callBack
*/
public void sendComplexForm(String url, Map<String, String> params, final CallBackJsonObject callBack) {
//表单对象,包含以input开始的对象
FormBody.Builder builder = new FormBody.Builder();
if (params != null && params.isEmpty()) {
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
}
RequestBody requestBody = builder.build();
//采用post提交
Request request = new Request.Builder().url(url).post(requestBody).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSucessJsonObjectMethod(response.body().string(), callBack);
}
}
});
}
/**
* 向服务器提交数据
* @param url
* @param content
* @param callback
*/
public void sendStringByPostMethod(String url, String content, final CallBackJsonObject callback) {
final Request request = new Request.Builder().url(url).post(RequestBody.create(MEDIA_TYPE_MARKDOWN, content)).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSucessJsonObjectMethod(response.body().toString(), callback);
}
}
});
}
public void asyncDownLoadImageByURL(String url, final CallBackBitmap callback) {
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
byte[] data = response.body().bytes();
Bitmap bitmap = new CropSquareTrans().transform(BitmapFactory.decodeByteArray(data, 0, data.length));
callback.onResponse(bitmap);
}
}
});
}
/**
* 请求返回的字节集数组对象
*
* @param data
* @param callBack
*/
private void onSucessByteMethod(final byte[] data, CallBackByte callBack) {
handler.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
try {
callBack.onResponse(data);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
interface CallBackString {
void onResponse(String result);
}
interface CallBackByte {
void onResponse(byte[] result);
}
interface CallBackBitmap {
void onResponse(Bitmap bitmap);
}
interface CallBackJsonObject {
void onResponse(JSONObject jsonObject);
}
}
使用方法如下
package com.liuan.ok_demo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import org.json.JSONObject;
import java.io.IOException;
import java.util.HashMap;
import androidx.appcompat.app.AppCompatActivity;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OkActivity extends AppCompatActivity implements View.OnClickListener {
/**
* 图片下载
*/
private ImageView mImageView;
private final static int SUCESS_STATUS = 1;
private final static int FAIL_STATUS = 2;
private static final String TAG = "OkActivity";
private String imgage_path = "http://lorempixel.com/800/400/sports/";
private String json_path = "https://randomuser.me/api/";
private String POST_PATH = "https://reqres.in/api/users";
private Handler handle = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SUCESS_STATUS:
byte[] result = (byte[]) msg.obj;
// 获取图片的数据
Bitmap tmp_bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
// 直接裁剪,返回裁剪后的数据
Bitmap bitmap = new CropSquareTrans().transform(tmp_bitmap);
mImageView.setImageBitmap(bitmap);
Log.e(TAG, "handleMessage: SUCESS_STATUS");
break;
case FAIL_STATUS:
Log.e(TAG, "handleMessage: FAIL_STATUS");
break;
}
}
};
private OkHttpClient client;
/**
* 图片下载
*/
private Button mBtLoadpic;
/**
* 加载数据
*/
private Button mBtLoadTexxt;
private OkManager okManager;
/**
* pot请求下载
*/
private Button mBtPost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ok);
initView();
}
private void initView() {
mImageView = (ImageView) findViewById(R.id.imageView);
client = new OkHttpClient();
okManager = OkManager.getInstance();
mBtLoadpic = (Button) findViewById(R.id.bt_loadpic);
mBtLoadpic.setOnClickListener(this);
mBtLoadTexxt = (Button) findViewById(R.id.bt_load_texxt);
mBtLoadTexxt.setOnClickListener(this);
mBtPost = (Button) findViewById(R.id.bt_post);
mBtPost.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
default:
break;
case R.id.bt_loadpic:
Log.e(TAG, "onClick: start");
// 使用的是get请求
Request request = new Request.Builder().get().url(imgage_path).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "onFailure: " + e.toString());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Message message = handle.obtainMessage();
Log.e(TAG, "onResponse: " + response.isSuccessful());
if (response.isSuccessful()) {
message.what = SUCESS_STATUS;
message.obj = response.body().bytes();
handle.sendMessage(message);
} else {
message.what = FAIL_STATUS;
}
}
});
Log.e(TAG, "onClick: end");
break;
case R.id.bt_load_texxt:
okManager.asyncJsonStringByURL(json_path, new OkManager.CallBackString() {
@Override
public void onResponse(String result) {
Log.e(TAG, "onResponse: " + result);
Toast.makeText(OkActivity.this, "" + result, Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.bt_post:
HashMap<String, String> hashMap = new HashMap();
hashMap.put("name", "morpheus");
hashMap.put("job", "leader");
okManager.sendComplexForm(POST_PATH, hashMap, new OkManager.CallBackJsonObject() {
@Override
public void onResponse(JSONObject jsonObject) {
Toast.makeText(OkActivity.this, ""+jsonObject.toString(), Toast.LENGTH_SHORT).show();
}
});
break;
}
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".OkActivity">
<Button
android:id="@+id/bt_loadpic"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="1dp"
android:text="图片下载"
app:layout_constraintBottom_toTopOf="@+id/bt_load_texxt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_post" />
<Button
android:id="@+id/bt_post"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:text="pot请求下载"
app:layout_constraintBottom_toTopOf="@+id/bt_loadpic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
android:id="@+id/bt_load_texxt"
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="16dp"
android:text="加载数据"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_loadpic" />
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="17dp"
android:layout_marginLeft="17dp"
android:layout_marginTop="18dp"
android:layout_marginEnd="17dp"
android:layout_marginRight="17dp"
android:layout_marginBottom="17dp"
app:layout_constraintBottom_toTopOf="@+id/bt_post"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher"
tools:srcCompat="@tools:sample/backgrounds/scenic[3]" />
</androidx.constraintlayout.widget.ConstraintLayout>