diff --git a/app/build.gradle b/app/build.gradle
index 0d4f278..645acaf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,7 +32,13 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+ implementation project(path:":netlibs")
+
+ api 'com.squareup.okhttp3:okhttp:3.14.9'
+ api 'com.squareup.retrofit2:retrofit:2.3.0'
+ api 'com.alibaba.fastjson2:fastjson2:2.0.47'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5be129f..ed400c6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
+ tools:targetApi="31">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/yutou/nettools/Api.java b/app/src/main/java/com/yutou/nettools/Api.java
new file mode 100644
index 0000000..8d1624c
--- /dev/null
+++ b/app/src/main/java/com/yutou/nettools/Api.java
@@ -0,0 +1,24 @@
+package com.yutou.nettools;
+
+
+import com.yutou.netlibs.http.API;
+
+import java.util.HashMap;
+
+public class Api extends API {
+
+ public Api(String url) {
+ super(url);
+ }
+
+ public Api(String url, HashMap params) {
+ super(url, params);
+
+ }
+ public static HttpApi getInstance(HashMap params){
+ return new Api("http://tools.yutou233.cn",params).createAPI(HttpApi.class);
+ }
+ public static HttpApi getInstance(){
+ return new Api("http://tools.yutou233.cn").createAPI(HttpApi.class);
+ }
+}
diff --git a/app/src/main/java/com/yutou/nettools/Bean.java b/app/src/main/java/com/yutou/nettools/Bean.java
new file mode 100644
index 0000000..8e776bb
--- /dev/null
+++ b/app/src/main/java/com/yutou/nettools/Bean.java
@@ -0,0 +1,34 @@
+package com.yutou.nettools;
+
+
+public class Bean {
+ String url;
+ String version;
+
+ public Bean() {
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @Override
+ public String toString() {
+ return "Bean{" +
+ "url='" + url + '\'' +
+ ", version='" + version + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/yutou/nettools/HttpApi.java b/app/src/main/java/com/yutou/nettools/HttpApi.java
new file mode 100644
index 0000000..84a8fa0
--- /dev/null
+++ b/app/src/main/java/com/yutou/nettools/HttpApi.java
@@ -0,0 +1,24 @@
+package com.yutou.nettools;
+
+
+import com.yutou.netlibs.http.HttpBody;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.Query;
+
+public interface HttpApi {
+ @GET("/public/request.do")
+ Call> getVersion();
+ @GET("tools/password/type/get/list.do")
+ Call>> getList(@Query("token")String token);
+ @FormUrlEncoded
+ @POST("/public/request.do")
+ Call> postVersion(@Field("test")String data);
+
+}
diff --git a/app/src/main/java/com/yutou/nettools/MainActivity.java b/app/src/main/java/com/yutou/nettools/MainActivity.java
new file mode 100644
index 0000000..3811900
--- /dev/null
+++ b/app/src/main/java/com/yutou/nettools/MainActivity.java
@@ -0,0 +1,48 @@
+package com.yutou.nettools;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+
+import com.yutou.netlibs.http.HttpBody;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ findViewById(R.id.button)
+ .setOnClickListener(v -> {
+ Api.getInstance().getList("")
+ .enqueue(new Callback>>() {
+ @Override
+ public void onResponse(Call>> call, Response>> response) {
+ System.out.println("response = " + response.body().getData());
+ }
+
+ @Override
+ public void onFailure(Call>> call, Throwable t) {
+
+ }
+ });
+ Api.getInstance().getVersion().enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ System.out.println("response = " + response.body().getData());
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+
+ }
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/yutou/nettools/Password.java b/app/src/main/java/com/yutou/nettools/Password.java
new file mode 100644
index 0000000..0bd19d3
--- /dev/null
+++ b/app/src/main/java/com/yutou/nettools/Password.java
@@ -0,0 +1,101 @@
+package com.yutou.nettools;
+
+
+public class Password {
+ private int id;
+ private String info;
+ private String password; // 实际应用中,密码不应该以明文形式存储或传输
+ private String title;
+ private String titlePinyin;
+ private int type;
+ private int uid;
+ private String url;
+ private String username;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getTitlePinyin() {
+ return titlePinyin;
+ }
+
+ public void setTitlePinyin(String titlePinyin) {
+ this.titlePinyin = titlePinyin;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getUid() {
+ return uid;
+ }
+
+ public void setUid(int uid) {
+ this.uid = uid;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ @Override
+ public String toString() {
+ return "Password{" +
+ "id=" + id +
+ ", info='" + info + '\'' +
+ ", password='" + password + '\'' +
+ ", title='" + title + '\'' +
+ ", titlePinyin='" + titlePinyin + '\'' +
+ ", type=" + type +
+ ", uid=" + uid +
+ ", url='" + url + '\'' +
+ ", username='" + username + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..ddad10b
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 3e927b1..16823ec 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,4 +18,9 @@ android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+
+systemProp.http.proxyHost=127.0.0.1
+systemProp.https.proxyHost=127.0.0.1
+systemProp.https.proxyPort=7980
+systemProp.http.proxyPort=7890
\ No newline at end of file
diff --git a/netlibs/.gitignore b/netlibs/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/netlibs/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/netlibs/build.gradle b/netlibs/build.gradle
new file mode 100644
index 0000000..9b2f60b
--- /dev/null
+++ b/netlibs/build.gradle
@@ -0,0 +1,42 @@
+plugins {
+ id 'com.android.library'
+}
+
+android {
+ namespace 'com.yutou.netlibs'
+ compileSdk 34
+
+ defaultConfig {
+ minSdk 28
+ targetSdk 34
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.11.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+
+ implementation 'com.squareup.okhttp3:okhttp:3.14.9'
+ implementation 'com.squareup.retrofit2:retrofit:2.3.0'
+ implementation 'com.alibaba.fastjson2:fastjson2:2.0.47'
+
+}
\ No newline at end of file
diff --git a/netlibs/proguard-rules.pro b/netlibs/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/netlibs/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/netlibs/src/androidTest/java/com/yutou/netlibs/ExampleInstrumentedTest.java b/netlibs/src/androidTest/java/com/yutou/netlibs/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..359fdd5
--- /dev/null
+++ b/netlibs/src/androidTest/java/com/yutou/netlibs/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.yutou.netlibs;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.yutou.netlibs", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/netlibs/src/main/AndroidManifest.xml b/netlibs/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6198cf7
--- /dev/null
+++ b/netlibs/src/main/AndroidManifest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/main/java/com/yutou/netlibs/converter/JsonCallAdapter.java b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonCallAdapter.java
new file mode 100644
index 0000000..6b099bb
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonCallAdapter.java
@@ -0,0 +1,19 @@
+package com.yutou.netlibs.converter;
+
+import org.jetbrains.annotations.Nullable;
+import retrofit2.CallAdapter;
+import retrofit2.Retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class JsonCallAdapter extends CallAdapter.Factory{
+ public static JsonCallAdapter create(){
+ return new JsonCallAdapter();
+ }
+ @Nullable
+ @Override
+ public CallAdapter, ?> get(Type type, Annotation[] annotations, Retrofit retrofit) {
+ return null;
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/converter/JsonConverterFactory.java b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonConverterFactory.java
new file mode 100644
index 0000000..668fc40
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonConverterFactory.java
@@ -0,0 +1,30 @@
+package com.yutou.netlibs.converter;
+
+import okhttp3.RequestBody;
+import okhttp3.ResponseBody;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class JsonConverterFactory extends Converter.Factory {
+ public static JsonConverterFactory create() {
+ return new JsonConverterFactory();
+ }
+
+ @Nullable
+ @Override
+ public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
+ // return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
+ return new JsonRequestBodyConverter<>();
+ }
+
+ @Nullable
+ @Override
+ public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
+ // return super.responseBodyConverter(type, annotations, retrofit);
+ return new JsonResponseBodyConverter<>();
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/converter/JsonRequestBodyConverter.java b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonRequestBodyConverter.java
new file mode 100644
index 0000000..6c289cc
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonRequestBodyConverter.java
@@ -0,0 +1,16 @@
+package com.yutou.netlibs.converter;
+
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+
+import java.io.IOException;
+
+public class JsonRequestBodyConverter implements Converter {
+ @Nullable
+ @Override
+ public RequestBody convert(T t) throws IOException {
+ return RequestBody.create(MediaType.parse("application/json);charset=UTF-8"), t.toString());
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/converter/JsonResponseBodyConverter.java b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonResponseBodyConverter.java
new file mode 100644
index 0000000..d75137f
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/converter/JsonResponseBodyConverter.java
@@ -0,0 +1,30 @@
+package com.yutou.netlibs.converter;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.netlibs.http.HttpBody;
+
+import okhttp3.ResponseBody;
+import org.jetbrains.annotations.Nullable;
+import retrofit2.Converter;
+
+import java.io.IOException;
+
+public class JsonResponseBodyConverter implements Converter {
+ @Nullable
+ @Override
+ public T convert(ResponseBody responseBody) throws IOException {
+ String string = new String(responseBody.bytes());
+ responseBody.close();
+ HttpBody body ;
+ try {
+ body = JSONObject.parseObject(string, HttpBody.class);
+ return (T) body;
+ } catch (Exception e) {
+ e.printStackTrace();
+ body = new HttpBody();
+ body.setSrc(string);
+ }
+ return (T) body;
+
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/API.java b/netlibs/src/main/java/com/yutou/netlibs/http/API.java
new file mode 100644
index 0000000..0d506ba
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/API.java
@@ -0,0 +1,56 @@
+package com.yutou.netlibs.http;
+
+import com.yutou.netlibs.converter.JsonCallAdapter;
+import com.yutou.netlibs.converter.JsonConverterFactory;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+public class API extends BaseAPI {
+ private String URL;
+ private HashMap params;
+
+ public API(String url, HashMap params) {
+ this.URL = url;
+ this.params = params;
+ }
+
+ public API(String url) {
+ this.URL = url;
+ this.params = new HashMap<>();
+ }
+
+
+ @Override
+ public T createAPI(Class t) {
+ HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("http");
+ loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
+ OkHttpClient.Builder builder = new OkHttpClient()
+ .newBuilder()
+
+ .addInterceptor(initQuery())
+ .addInterceptor(loggingInterceptor);
+ return create(builder.build(),
+ JsonConverterFactory.create(),
+ JsonCallAdapter.create(),
+ URL,
+ t);
+ }
+
+ public Interceptor initQuery() {
+ Interceptor addQueryParameterInterceptor = new Interceptor() {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ //配置公共参数
+ request = new ParamsContext(params,request).getInRequest();
+ return chain.proceed(request);
+ }
+ };
+ return addQueryParameterInterceptor;
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/BaseAPI.java b/netlibs/src/main/java/com/yutou/netlibs/http/BaseAPI.java
new file mode 100644
index 0000000..6d2d9b8
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/BaseAPI.java
@@ -0,0 +1,45 @@
+package com.yutou.netlibs.http;
+
+import okhttp3.OkHttpClient;
+import retrofit2.CallAdapter;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+public abstract class BaseAPI {
+ public abstract T createAPI(Class t);
+ /**
+ * 创建一个接口方法
+ *
+ * @param okHttpClient okhttp客户端
+ * @param converterFactory 处理工厂类
+ * @param callAdapterFactory 请求适配器工厂
+ * @param baseUrl 基础地质
+ * @param service 接口
+ * @param 接口泛型
+ * @return 接口
+ */
+ public T create(OkHttpClient okHttpClient,
+ Converter.Factory converterFactory,
+ CallAdapter.Factory callAdapterFactory,
+ String baseUrl,
+ Class service) {
+ Retrofit.Builder builder = new Retrofit.Builder()
+ //基础url
+ .baseUrl(baseUrl)
+ //客户端OKHttp
+ .client(okHttpClient);
+ //添加转换工厂
+ if (null != converterFactory) {
+ builder.addConverterFactory(converterFactory);
+ }
+ //添加请求工厂
+ if (null != callAdapterFactory) {
+ builder.addCallAdapterFactory(callAdapterFactory);
+ }
+ //创建retrofit对象
+ Retrofit retrofit = builder.build();
+
+ //返回创建的api
+ return retrofit.create(service);
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/GetRequestParams.java b/netlibs/src/main/java/com/yutou/netlibs/http/GetRequestParams.java
new file mode 100644
index 0000000..d996524
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/GetRequestParams.java
@@ -0,0 +1,25 @@
+package com.yutou.netlibs.http;
+
+
+import okhttp3.HttpUrl;
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public class GetRequestParams implements IRequestParam {
+ /**
+ * 构建Request
+ *
+ * @param request
+ * @return
+ */
+ @Override
+ public Request getRequest(HashMap map, Request request) {
+ //添加公共参数
+ HttpUrl.Builder builder = request.url().newBuilder();
+ for (String key : map.keySet()) {
+ builder.addQueryParameter(key, String.valueOf(map.get(key)));
+ }
+ return request.newBuilder().url(builder.build()).build();
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/HttpBody.java b/netlibs/src/main/java/com/yutou/netlibs/http/HttpBody.java
new file mode 100644
index 0000000..85da1dd
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/HttpBody.java
@@ -0,0 +1,40 @@
+package com.yutou.netlibs.http;
+
+public class HttpBody {
+ private String msg;
+ private int code;
+ private T data;
+ private String src;
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public String getSrc() {
+ return src;
+ }
+
+ public void setSrc(String src) {
+ this.src = src;
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/HttpLoggingInterceptor.java b/netlibs/src/main/java/com/yutou/netlibs/http/HttpLoggingInterceptor.java
new file mode 100644
index 0000000..45bb196
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/HttpLoggingInterceptor.java
@@ -0,0 +1,213 @@
+package com.yutou.netlibs.http;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import okhttp3.Connection;
+import okhttp3.Headers;
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okhttp3.internal.http.HttpHeaders;
+import okio.Buffer;
+
+public class HttpLoggingInterceptor implements Interceptor {
+
+ private static final String TAG = "HttpLog";
+ private static final Charset UTF8 = StandardCharsets.UTF_8;
+
+ private volatile Level printLevel = Level.NONE;
+ private java.util.logging.Level colorLevel;
+ private Logger logger;
+
+ public enum Level {
+ NONE, //不打印log
+ BASIC, //只打印 请求首行 和 响应首行
+ HEADERS, //打印请求和响应的所有 Header
+ BODY //所有数据全部打印
+ }
+
+ public HttpLoggingInterceptor(String tag) {
+ logger = Logger.getLogger(tag);
+ colorLevel = java.util.logging.Level.ALL;
+ }
+
+ public void setPrintLevel(Level level) {
+ if (printLevel == null)
+ throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
+ printLevel = level;
+ }
+
+ public void setColorLevel(java.util.logging.Level level) {
+ colorLevel = level;
+ }
+
+ private void log(String message) {
+ logger.log(colorLevel, message);
+ System.err.println(message);
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ if (printLevel == Level.NONE) {
+ return chain.proceed(request);
+ }
+
+ //请求日志拦截
+ // logForRequest(request, chain.connection());
+
+ //执行请求,计算请求时间
+ long startNs = System.nanoTime();
+ Response response;
+ try {
+ response = chain.proceed(request);
+ } catch (Exception e) {
+ log("<-- HTTP FAILED: " + e);
+ throw e;
+ }
+ long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
+
+ //响应日志拦截
+ return logForResponse(request, response, tookMs);
+ }
+
+ private void logForRequest(Request request, Connection connection) throws IOException {
+ boolean logBody = (printLevel == Level.BODY);
+ boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
+ RequestBody requestBody = request.body();
+ boolean hasRequestBody = requestBody != null;
+ Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
+ try {
+ String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
+ log(requestStartMessage);
+
+ if (logHeaders) {
+ if (hasRequestBody) {
+ // Request body headers are only present when installed as a network interceptor. Force
+ // them to be included (when available) so there values are known.
+ if (requestBody.contentType() != null) {
+ log("\tContent-Type: " + requestBody.contentType());
+ }
+ if (requestBody.contentLength() != -1) {
+ log("\tContent-Length: " + requestBody.contentLength());
+ }
+ }
+ Headers headers = request.headers();
+ for (int i = 0, count = headers.size(); i < count; i++) {
+ String name = headers.name(i);
+ // Skip headers from the request body as they are explicitly logged above.
+ if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
+ log("\t" + name + ": " + headers.value(i));
+ }
+ }
+
+ log(" ");
+ if (logBody && hasRequestBody) {
+ if (isPlaintext(requestBody.contentType())) {
+ bodyToString(request);
+ } else {
+ log("\tbody: maybe [binary body], omitted!");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.log(colorLevel, "error", e);
+ } finally {
+ log("--> END " + request.method());
+ }
+ }
+
+ private Response logForResponse(Request request, Response response, long tookMs) {
+ Response.Builder builder = response.newBuilder();
+ Response clone = builder.build();
+ ResponseBody responseBody = clone.body();
+ RequestBody requestBody = request.body();
+ boolean hasRequestBody = requestBody != null;
+ boolean logBody = (printLevel == Level.BODY);
+ boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
+
+ try {
+ log("<-- " + clone.code() + ' ' + clone.message() + ' ' + clone.request().url() + " (" + tookMs + "ms)");
+ if (logHeaders) {
+ Headers headers = clone.headers();
+ for (int i = 0, count = headers.size(); i < count; i++) {
+ log("\t" + headers.name(i) + ": " + headers.value(i));
+ }
+ log(" ");
+ if (logBody && hasRequestBody) {
+ if (isPlaintext(requestBody.contentType())) {
+ bodyToString(request);
+ } else {
+ log("\trequest: maybe [binary body], omitted!");
+ }
+ }
+ if (logBody && HttpHeaders.hasBody(clone)) {
+ if (responseBody == null) return response;
+
+ if (isPlaintext(responseBody.contentType())) {
+ byte[] bytes = responseBody.bytes();// IOUtils.toByteArray(responseBody.byteStream());
+ MediaType contentType = responseBody.contentType();
+ String body = new String(bytes, getCharset(contentType));
+ log("\tbody:" + body);
+ responseBody = ResponseBody.create(responseBody.contentType(), bytes);
+ return response.newBuilder().body(responseBody).build();
+ } else {
+ log("\tbody: maybe [binary body], omitted!");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.log(colorLevel, "error", e);
+ } finally {
+ log("<-- END HTTP");
+ }
+ return response;
+ }
+
+ private static Charset getCharset(MediaType contentType) {
+ Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
+ if (charset == null) charset = UTF8;
+ return charset;
+ }
+
+ /**
+ * Returns true if the body in question probably contains human readable text. Uses a small sample
+ * of code points to detect unicode control characters commonly used in binary file signatures.
+ */
+ private static boolean isPlaintext(MediaType mediaType) {
+ if (mediaType == null) return false;
+ if (mediaType.type() != null && mediaType.type().equals("text")) {
+ return true;
+ }
+ String subtype = mediaType.subtype();
+ if (subtype != null) {
+ subtype = subtype.toLowerCase();
+ if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
+ return true;
+ }
+ return false;
+ }
+
+ private void bodyToString(Request request) {
+ try {
+ Request copy = request.newBuilder().build();
+ RequestBody body = copy.body();
+ if (body == null) return;
+ Buffer buffer = new Buffer();
+ body.writeTo(buffer);
+ Charset charset = getCharset(body.contentType());
+ log("\tbody:" + buffer.readString(charset));
+ } catch (Exception e) {
+ logger.log(colorLevel, "error", e);
+ }
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/IRequestParam.java b/netlibs/src/main/java/com/yutou/netlibs/http/IRequestParam.java
new file mode 100644
index 0000000..aa6074e
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/IRequestParam.java
@@ -0,0 +1,9 @@
+package com.yutou.netlibs.http;
+
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public interface IRequestParam {
+ Request getRequest(HashMap map, Request request);
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/ParamsContext.java b/netlibs/src/main/java/com/yutou/netlibs/http/ParamsContext.java
new file mode 100644
index 0000000..9944e40
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/ParamsContext.java
@@ -0,0 +1,29 @@
+package com.yutou.netlibs.http;
+
+
+import okhttp3.Request;
+
+import java.util.HashMap;
+
+public class ParamsContext {
+ private IRequestParam iRequestParam;
+ private Request request;
+ private HashMap map;
+
+ public ParamsContext(HashMap map,Request request) {
+ this.map=map;
+ this.request = request;
+ }
+
+ public Request getInRequest() {
+ switch (request.method()) {
+ case "GET":
+ iRequestParam = new GetRequestParams();
+ break;
+ case "POST":
+ iRequestParam = new PostRequestParams();
+ break;
+ }
+ return iRequestParam.getRequest(map,request);
+ }
+}
diff --git a/netlibs/src/main/java/com/yutou/netlibs/http/PostRequestParams.java b/netlibs/src/main/java/com/yutou/netlibs/http/PostRequestParams.java
new file mode 100644
index 0000000..07588a8
--- /dev/null
+++ b/netlibs/src/main/java/com/yutou/netlibs/http/PostRequestParams.java
@@ -0,0 +1,65 @@
+package com.yutou.netlibs.http;
+
+
+import com.alibaba.fastjson2.JSONObject;
+
+import okhttp3.*;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class PostRequestParams implements IRequestParam {
+ @Override
+ public Request getRequest(HashMap map, Request request) {
+ if (request.body() instanceof FormBody) {
+ FormBody.Builder bodyBuilder = new FormBody.Builder();
+ FormBody formBody = (FormBody) request.body();
+
+ for (int i = 0; i < formBody.size(); i++) {
+ bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
+ }
+ for (String key : map.keySet()) {
+ bodyBuilder.addEncoded(key, String.valueOf(map.get(key)));
+ }
+ formBody = bodyBuilder.build();
+ request = request.newBuilder().post(formBody).build();
+ } else if (request.body() != null) {
+ RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),toUrlParams(map));
+ request = request.newBuilder().post(request.body())
+ .post(requestBody).build();
+ }
+ return request;
+ }
+
+ public static String toUrlParams(JSONObject json) {
+ StringBuilder string = new StringBuilder();
+ Set keys = json.keySet();
+ for (String key : keys) {
+ try {
+ string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ try {
+ string.append("&").append(URLEncoder.encode(key,"UTF-8")).append("=");
+ // string += "&" + key + "=";
+ } catch (Exception e1) {
+ string.append("&").append(key).append("=");
+ }
+ }
+ }
+
+ string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", ""));
+ return string.toString();
+ }
+
+ public static String toUrlParams(Map map) {
+ StringBuilder builder = new StringBuilder();
+ for (String key : map.keySet()) {
+ builder.append(key).append("=").append(map.get(key)).append("&");
+ }
+ return builder.substring(0, builder.length() - 1);
+ }
+}
diff --git a/netlibs/src/main/res/drawable/ic_launcher_background.xml b/netlibs/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/netlibs/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/netlibs/src/main/res/drawable/ic_launcher_foreground.xml b/netlibs/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/netlibs/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/mipmap-anydpi/ic_launcher.xml b/netlibs/src/main/res/mipmap-anydpi/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/netlibs/src/main/res/mipmap-anydpi/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/netlibs/src/main/res/mipmap-anydpi/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/netlibs/src/main/res/mipmap-anydpi/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/mipmap-hdpi/ic_launcher.webp b/netlibs/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/netlibs/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/netlibs/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/netlibs/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/netlibs/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/netlibs/src/main/res/mipmap-mdpi/ic_launcher.webp b/netlibs/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/netlibs/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/netlibs/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/netlibs/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/netlibs/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/netlibs/src/main/res/mipmap-xhdpi/ic_launcher.webp b/netlibs/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/netlibs/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/netlibs/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/netlibs/src/main/res/values-night/themes.xml b/netlibs/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..b161c53
--- /dev/null
+++ b/netlibs/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/values/colors.xml b/netlibs/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/netlibs/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/values/strings.xml b/netlibs/src/main/res/values/strings.xml
new file mode 100644
index 0000000..274a7b7
--- /dev/null
+++ b/netlibs/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ NetLibs
+
\ No newline at end of file
diff --git a/netlibs/src/main/res/values/themes.xml b/netlibs/src/main/res/values/themes.xml
new file mode 100644
index 0000000..3e5e538
--- /dev/null
+++ b/netlibs/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/netlibs/src/test/java/com/yutou/netlibs/ExampleUnitTest.java b/netlibs/src/test/java/com/yutou/netlibs/ExampleUnitTest.java
new file mode 100644
index 0000000..b0d260e
--- /dev/null
+++ b/netlibs/src/test/java/com/yutou/netlibs/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.yutou.netlibs;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index d83c931..ed15ff3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,3 +15,4 @@ dependencyResolutionManagement {
rootProject.name = "NetTools"
include ':app'
+include ':netlibs'