这应该是我封装的第一个网络框架,内部封装了普通的get请求,post请求,上传图片,上传头像,以及Header、包含token同时携带body数据,这里凡是含有项目封装的都是转成JSON数据之后传到服务器的。如果只是一般的请求我们只是用的普通的post请求,get请求就可以
关联篇
网上代码千千万,很少有能直接就用的,多多少少要做一些小修改,少年,加油哦 !
效果
Effect
Log打印的返回数据
基础配置
权限加入
<uses-permission android:name="android.permission.INTERNET" />
build.gradle(app) - 加入依赖
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.6.0'
compile 'com.alibaba:fastjson:1.2.31'
compile 'com.alibaba:fastjson:1.1.57.android'
代码实践
封装准备
你知道我对你不仅仅是喜欢,天气不错,继续向下 ~
封装回调 - 回调接口
package com.bakheet.effect.okhttpframe;
import java.io.IOException;
/**
* Created by YongLiu on 2017/10/26.
*/
public interface OnResultListener<T> {
void onSuccess(String response) throws IOException;
void onFailure(Throwable t);
}
解析工具 - FastJsonTools
用于解析服务器返回数据的工具类
package com.bakheet.effect.okhttpframe;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by YongLiu on 2017/9/13.
*/
public class FastJsonTools {
/**
* 用fastjson 将json字符串解析为一个 JavaBean
*
* @param jsonString
* @param cls
* @return
*/
public static <T> T getBean(String jsonString, Class<T> cls) {
T t = null;
try {
t = JSON.parseObject(jsonString, cls);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return t;
}
/**
* 用fastjson 将json字符串 解析成为一个 List<JavaBean> 及 List<String>
*
* @param jsonString
* @param cls
* @return
*/
public static <T> List<T> getBeans(String jsonString, Class<T> cls) {
List<T> list = new ArrayList<T>();
try {
list = JSON.parseArray(jsonString, cls);
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
/**
* 用fastjson 将jsonString 解析成 List<Map<String,Object>>
*
* @param jsonString
* @return
*/
public static List<Map<String, Object>> getListMap(String jsonString) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
try {
// 两种写法
// list = JSON.parseObject(jsonString, new
// TypeReference<List<Map<String, Object>>>(){}.getType());
list = JSON.parseObject(jsonString,
new TypeReference<List<Map<String, Object>>>() {
});
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
}
基类封装 - BaseModel
返回的一个基类Model层
package com.bakheet.effect.okhttpframe;
public class BaseModel<T> {
private String result;
private String desc;
private String error;
private String exception;
private String message;
private String path;
private int status;
private String timestamp;
private T data;
public String getResult() {
return result;
}
public String getDesc() {
return desc;
}
public String getError() {
return error;
}
public String getException() {
return exception;
}
public String getMessage() {
return message;
}
public String getPath() {
return path;
}
public int getStatus() {
return status;
}
public String getTimestamp() {
return timestamp;
}
public void setResult(String result) {
this.result = result;
}
public void setDesc(String desc) {
this.desc = desc;
}
public void setError(String error) {
this.error = error;
}
public void setException(String exception) {
this.exception = exception;
}
public void setMessage(String message) {
this.message = message;
}
public void setPath(String path) {
this.path = path;
}
public void setStatus(int status) {
this.status = status;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
封装工具 - HttpUtils
package com.bakheet.effect.okhttpframe;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by YongLiu on 2017/9/13.
*/
public class HttpUtils {
private static OkHttpClient client = null;
private static MultipartBody.Builder builder;
private static MediaType media_type;
private HttpUtils() {
}
public static OkHttpClient getInstance() {
if (client == null) {
synchronized (HttpUtils.class) {
if (client == null) {
client = new OkHttpClient();
}
}
}
return client;
}
/**
* Get请求
*
* @param url
* @param callback
*/
public static void doGet(String url, Callback callback) {
Request request = new Request.Builder()
.url(url)
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 项目封装 - Get数据 - 头形式上传
*/
public static void doHeadGet(String url, Callback callback) {
Request request = new Request.Builder()
.url(url)
// .addHeader("token","4cDA9M")
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* Post请求发送键值对数据
*
* @param url
* @param mapParams
* @param callback
*/
public static void doPost(String url, Map<String, String> mapParams, Callback callback) {
FormBody.Builder builder = new FormBody.Builder();
for (String key : mapParams.keySet()) {
builder.add(key, mapParams.get(key));
}
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* Post请求发送JSON数据
*
* @param url
* @param jsonParams
* @param callback
*/
public static void doPost(String url, String jsonParams, Callback callback) {
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8")
, jsonParams);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 项目封装 - Post数据 - 头形式上传
*/
public static void doHeadPost(String url, String jsonParams, final OnResultListener resultListener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8")
, jsonParams);
Request request = new Request.Builder()
.url(url)
.addHeader("token","c794fa2810cdd726a0d9f35614a2e43de2bee65a")
.post(body)
.build();
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
resultListener.onFailure(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseBody = response.body().string();
if (!TextUtils.isEmpty(responseBody)) {
BaseModel bean = FastJsonTools.getBean(responseBody, BaseModel.class);
String result = bean.getResult();
if ("0".equals(result)) {
resultListener.onSuccess(responseBody);
} else {
Log.e("tag", "result =" + result);
Log.e("tag", "Dest =" + bean.getDesc());
}
} else {
Log.e("tag", "请求返回的是串");
}
}
});
}
/**
* 上传文件
*
* @param url
* @param pathName
* @param fileName
* @param callback
*/
public static void doFile(String url, String pathName, String fileName, Callback callback) {
//判断文件类型
MediaType mediaType = MediaType.parse(judgeType(pathName));
//创建文件参数
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(mediaType.type(), fileName,
RequestBody.create(mediaType, new File(pathName)));
//发出请求参数
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
/**
* 项目封装 - 上传头像
*/
public static void doHeadFile(String url, String pathName, String fileName, Callback callback) {
//判断文件类型
MediaType mediaType = MediaType.parse(judgeType(pathName));
//创建文件参数
builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("avatar", fileName,
RequestBody.create(MEDIA_TYPE_PNG, new File(pathName)));
//发出请求参数
Request request = new Request.Builder()
// .addHeader("token", SharedPreferencesUtil.getString(CarMasterApplication.getContext(), "token"))
.url(url)
.post(builder.build())
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 项目封装 - 上传图片
*/
public static void doMoreFile(Context context, final String url, List<String> lists, String pathName, String fileName, final Callback callback) {
final List<File> endList = new ArrayList<>();
for (int i = 0; i < lists.size(); i++) {
//判断文件类型
media_type = MediaType.parse(judgeType(lists.get(i).toString()));
}
List<File> imgList = new ArrayList<>();
for (int i = 0; i < lists.size(); i++) {
File file = new File(lists.get(i));
imgList.add(file);
}
for (int c = 0; c < imgList.size(); c++) {
long length = imgList.get(c).length();
// File yasuo = AppUtil.yasuo(imgList.get(c));
// endList.add(yasuo);
}
builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
for (File files : endList) {
if (files.exists()) {
builder.addFormDataPart("img", files.getName(),
RequestBody.create(MEDIA_TYPE_PNG, new File(files.toString())));
}
}
Request request = new Request.Builder()
// .addHeader("token", SharedPreferencesUtil.getString(context, "token"))
.url(url)
.post(builder.build())
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 根据文件路径判断MediaType
*
* @param path
* @return
*/
private static String judgeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null) {
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}
/**
* 下载文件
*
* @param url
* @param fileDir
* @param fileName
*/
public static void downFile(String url, final String fileDir, final String fileName) {
Request request = new Request.Builder()
.url(url)
.build();
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();
File file = new File(fileDir, fileName);
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
}
}
});
}
}
关键认知扩展工作(双层回调,底层封装状态判断):
/**
* 项目封装 - Post数据 - 头形式上传
*/
public static void doHeadPost(String url, String jsonParams, final OnResultListener resultListener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8")
, jsonParams);
Request request = new Request.Builder()
.url(url)
.addHeader("token", "c794fa2810cdd726a0d9f35614a2e43de2bee65a")
.post(body)
.build();
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
resultListener.onFailure(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseBody = response.body().string();
if (!TextUtils.isEmpty(responseBody)) {
BaseModel bean = FastJsonTools.getBean(responseBody, BaseModel.class);
String result = bean.getResult();
if ("0".equals(result)) {
resultListener.onSuccess(responseBody);
} else {
Log.e("tag", "result =" + result);
Log.e("tag", "Dest =" + bean.getDesc());
}
} else {
Log.e("tag", "请求返回的是串");
}
}
});
}
使用方式
MainActivity
package com.bakheet.effect.okhttpframe;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.util.HashMap;
import okhttp3.Response;
/**
* @author YongLiu
*/
public class MainActivity extends AppCompatActivity {
private TextView mContent;
private TextView mBtn;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String response = (String) msg.obj;
mContent.setText(response);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (TextView) findViewById(R.id.btn);
mContent = (TextView) findViewById(R.id.tv_content);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setData("1", handler);
}
});
}
public void setData(String tag, final Handler handler) {
HashMap map = new HashMap<>();
map.put("tag", tag);
String jsonParams = JSON.toJSONString(map);
//这个接口是我当前项目用到的一个post请求接口,需要头部带token,然后其余在body中
HttpUtils.doHeadPost("http://api.phc-dow.com/user/comment/page" + "?pageNum=" + 1 + "&" + "pageSize=" + 5, jsonParams, new OnResultListener() {
@Override
public void onSuccess(String response) throws IOException {
Log.e("tag ", "Main =" + response);
Message message = new Message();
message.obj = response;
handler.sendMessage(message);
}
@Override
public void onFailure(Throwable t) {
Log.e("tag ", "Main 失败回调");
}
});
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.bakheet.effect.okhttpframe.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/tv_content"
/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#f63"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击"
android:padding="8dp"
android:gravity="center"
android:id="@+id/btn"
/>
</LinearLayout>