Skip to content

Commit

Permalink
抽取和封装 RequestBody 请求策略
Browse files Browse the repository at this point in the history
优化 ThreadSchedulers 字段命名
  • Loading branch information
getActivity committed Oct 4, 2023
1 parent af97154 commit ec8ed4c
Show file tree
Hide file tree
Showing 17 changed files with 322 additions and 260 deletions.
10 changes: 5 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId 'com.hjq.easy.demo'
minSdkVersion 21
targetSdkVersion 31
versionCode 1202
versionName '12.2'
versionCode 1205
versionName '12.5'
}

// 支持 JDK 1.8
Expand Down Expand Up @@ -48,9 +48,9 @@ android {
}
}

applicationVariants.all { variant ->
applicationVariants.configureEach { variant ->
// apk 输出文件名配置
variant.outputs.all { output ->
variant.outputs.configureEach { output ->
outputFileName = rootProject.getName() + '.apk'
}
}
Expand All @@ -73,7 +73,7 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.12.13'

// 吐司框架:https://github.com/getActivity/Toaster
implementation 'com.github.getActivity:Toaster:12.3'
implementation 'com.github.getActivity:Toaster:12.5'

// 权限请求框架:https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:18.3'
Expand Down
17 changes: 9 additions & 8 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ android {

defaultConfig {
minSdkVersion 16
versionCode 1202
versionName "12.2"
versionCode 1205
versionName "12.5"
}

// 使用 JDK 1.8
Expand All @@ -20,9 +20,9 @@ android {
exclude 'META-INF/*******'
}

android.libraryVariants.all { variant ->
android.libraryVariants.configureEach { variant ->
// aar 输出文件名配置
variant.outputs.all { output ->
variant.outputs.configureEach { output ->
outputFileName = "${rootProject.name}-${android.defaultConfig.versionName}.aar"
}
}
Expand All @@ -45,23 +45,24 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0'
}

tasks.withType(Javadoc) {
tasks.withType(Javadoc).configureEach {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}

task sourcesJar(type: Jar) {
tasks.register('sourcesJar', Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}

task javadoc(type: Javadoc) {
tasks.register('javadoc', Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

task javadocJar(type: Jar, dependsOn: javadoc) {
tasks.register('javadocJar', Jar) {
dependsOn javadoc
classifier = 'javadoc'
from javadoc.destinationDir
}
Expand Down
2 changes: 1 addition & 1 deletion library/src/main/java/com/hjq/http/EasyConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static EasyConfig with(OkHttpClient client) {
private HashMap<String, String> mHeaders;

/** 线程调度器 */
private ThreadSchedulers mThreadSchedulers = ThreadSchedulers.MainThread;
private ThreadSchedulers mThreadSchedulers = ThreadSchedulers.MAIN;

/** 日志开关 */
private boolean mLogEnabled = true;
Expand Down
4 changes: 2 additions & 2 deletions library/src/main/java/com/hjq/http/EasyUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ public static void runOnIOThread(Runnable runnable) {
*/
public static void runOnAssignThread(ThreadSchedulers schedulers, Runnable runnable) {
switch (schedulers) {
case IOThread:
case IO:
if (isMainThread()) {
runOnIOThread(runnable);
} else {
runnable.run();
}
break;
case MainThread:
case MAIN:
default:
if (isMainThread()) {
runnable.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public abstract class BaseCallback implements Callback {
public BaseCallback(@NonNull HttpRequest<?> request) {
mHttpRequest = request;
// Lifecycle addObserver 需要在主线程中执行,所以这里要做一下线程转换
EasyUtils.runOnAssignThread(ThreadSchedulers.MainThread,
EasyUtils.runOnAssignThread(ThreadSchedulers.MAIN,
() -> HttpLifecycleManager.register(mHttpRequest.getLifecycleOwner()));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.hjq.http.config;

import com.hjq.http.model.HttpParams;
import com.hjq.http.request.HttpRequest;
import okhttp3.RequestBody;

/**
* author : Android 轮子哥
* github : https://github.com/getActivity/EasyHttp
* time : 2023/09/23
* desc : 请求 Body 策略接口
*/
public interface IRequestBodyStrategy {

/**
* 添加参数
*/
void addParams(HttpParams params, String key, Object value);

/**
* 创建 RequestBody
*/
RequestBody createRequestBody(HttpRequest<?> httpRequest, HttpParams params);
}
6 changes: 3 additions & 3 deletions library/src/main/java/com/hjq/http/config/IRequestServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import androidx.annotation.NonNull;

import com.hjq.http.model.BodyType;
import com.hjq.http.model.RequestBodyType;
import com.hjq.http.model.CacheMode;

/**
Expand All @@ -17,9 +17,9 @@ public interface IRequestServer extends

@NonNull
@Override
default BodyType getBodyType() {
default IRequestBodyStrategy getBodyType() {
// 默认以表单的方式提交
return BodyType.FORM;
return RequestBodyType.FORM;
}

@NonNull
Expand Down
4 changes: 1 addition & 3 deletions library/src/main/java/com/hjq/http/config/IRequestType.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import androidx.annotation.NonNull;

import com.hjq.http.model.BodyType;

/**
* author : Android 轮子哥
* github : https://github.com/getActivity/EasyHttp
Expand All @@ -16,5 +14,5 @@ public interface IRequestType {
* 获取参数的提交类型
*/
@NonNull
BodyType getBodyType();
IRequestBodyStrategy getBodyType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package com.hjq.http.config.impl;

import android.text.TextUtils;
import com.hjq.http.EasyLog;
import com.hjq.http.body.UpdateBody;
import com.hjq.http.config.IRequestBodyStrategy;
import com.hjq.http.model.FileContentResolver;
import com.hjq.http.model.HttpParams;
import com.hjq.http.request.HttpRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import okhttp3.FormBody;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okio.Okio;

/**
* author : Android 轮子哥
* github : https://github.com/getActivity/EasyHttp
* time : 2023/09/23
* desc : RequestBody 表单策略实现接口
*/
public class RequestFormBodyStrategy implements IRequestBodyStrategy {

@Override
public void addParams(HttpParams params, String key, Object value) {
// 表单提交
params.put(key, value);
}

@Override
public RequestBody createRequestBody(HttpRequest<?> httpRequest, HttpParams params) {
if (!params.isEmpty() && params.isMultipart()) {
return createMultipartRequestBody(httpRequest, params);
}
return createFormRequestBody(params);
}

public RequestBody createFormRequestBody(HttpParams params) {
FormBody.Builder bodyBuilder = new FormBody.Builder();
if (params.isEmpty()) {
return bodyBuilder.build();
}

for (String key : params.getKeys()) {
Object value = params.get(key);

if (!(value instanceof List)) {
bodyBuilder.add(key, String.valueOf(value));
continue;
}

List<?> list = (List<?>) value;
for (Object itemValue : list) {
if (itemValue == null) {
continue;
}
bodyBuilder.add(key, String.valueOf(itemValue));
}
}
return bodyBuilder.build();
}

public RequestBody createMultipartRequestBody(HttpRequest<?> httpRequest, HttpParams params) {
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
bodyBuilder.setType(MultipartBody.FORM);
for (String key : params.getKeys()) {
Object value = params.get(key);

if (value instanceof Map) {
// 如果这是一个 Map 集合
Map<?, ?> map = ((Map<?, ?>) value);
for (Object itemKey : map.keySet()) {
if (itemKey == null) {
continue;
}
Object itemValue = map.get(itemKey);
if (itemValue == null) {
continue;
}
addFormData(httpRequest, bodyBuilder, String.valueOf(itemKey), itemValue);
}
continue;
}

if (value instanceof List) {
// 如果这是一个 List 集合
List<?> list = (List<?>) value;
for (Object itemValue : list) {
if (itemValue == null) {
continue;
}
addFormData(httpRequest, bodyBuilder, key, itemValue);
}
continue;
}

addFormData(httpRequest, bodyBuilder, key, value);
}

try {
return bodyBuilder.build();
} catch (IllegalStateException ignored) {
// 如果参数为空则会抛出异常:Multipart body must have at least one part.
return new FormBody.Builder().build();
}
}

/**
* 添加参数
*/
private void addFormData(HttpRequest<?> httpRequest, MultipartBody.Builder bodyBuilder, String key, Object object) {
if (object instanceof File) {
// 如果这是一个 File 对象
File file = (File) object;
String fileName = null;
if (file instanceof FileContentResolver) {
fileName = ((FileContentResolver) file).getFileName();
}
if (TextUtils.isEmpty(fileName)) {
fileName = file.getName();
}

try {
MultipartBody.Part part;
if (file instanceof FileContentResolver) {
FileContentResolver fileContentResolver = (FileContentResolver) file;
InputStream inputStream = fileContentResolver.openInputStream();
part = MultipartBody.Part.createFormData(key, fileName, new UpdateBody(
Okio.source(inputStream), fileContentResolver.getContentType(),
fileName, inputStream.available()));
} else {
part = MultipartBody.Part.createFormData(key, fileName, new UpdateBody(file));
}
bodyBuilder.addPart(part);
} catch (FileNotFoundException e) {
// 文件不存在,将被忽略上传
EasyLog.printLog(httpRequest, "File does not exist, will be ignored upload: " +
key + " = " + file.getPath());
} catch (IOException e) {
EasyLog.printThrowable(httpRequest, e);
// 文件流读取失败,将被忽略上传
EasyLog.printLog(httpRequest, "File stream reading failed and will be ignored upload: " +
key + " = " + file.getPath());
}
return;
}

if (object instanceof InputStream) {
// 如果这是一个 InputStream 对象
InputStream inputStream = (InputStream) object;
try {
bodyBuilder.addPart(MultipartBody.Part.createFormData(key, null, new UpdateBody(inputStream, key)));
} catch (IOException e) {
EasyLog.printThrowable(httpRequest, e);
}
return;
}

if (object instanceof RequestBody) {
// 如果这是一个自定义的 RequestBody 对象
RequestBody requestBody = (RequestBody) object;
if (requestBody instanceof UpdateBody) {
bodyBuilder.addPart(MultipartBody.Part.createFormData(key,
((UpdateBody) requestBody).getKeyName(), requestBody));
} else {
bodyBuilder.addPart(MultipartBody.Part.createFormData(key, null, requestBody));
}
return;
}

if (object instanceof MultipartBody.Part) {
// 如果这是一个自定义的 MultipartBody.Part 对象
bodyBuilder.addPart((MultipartBody.Part) object);
return;
}

// 如果这是一个普通参数
bodyBuilder.addFormDataPart(key, String.valueOf(object));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.hjq.http.config.impl;

import com.hjq.http.EasyUtils;
import com.hjq.http.body.JsonBody;
import com.hjq.http.config.IRequestBodyStrategy;
import com.hjq.http.model.HttpParams;
import com.hjq.http.request.HttpRequest;
import okhttp3.RequestBody;

/**
* author : Android 轮子哥
* github : https://github.com/getActivity/EasyHttp
* time : 2023/09/23
* desc : RequestBody Json 策略实现接口
*/
public class RequestJsonBodyStrategy implements IRequestBodyStrategy {

@Override
public void addParams(HttpParams params, String key, Object value) {
// Json 提交
params.put(key, EasyUtils.convertObject(value));
}

@Override
public RequestBody createRequestBody(HttpRequest<?> httpRequest, HttpParams params) {
return new JsonBody(params.getParams());
}
}
Loading

0 comments on commit ec8ed4c

Please sign in to comment.