You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
12 KiB

package com.community.pocket.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Looper;
import android.util.Patterns;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.MutableLiveData;
import com.community.pocket.BuildConfig;
import com.community.pocket.R;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HttpUtil {
private static final Map<String, HttpRequest> map = new HashMap<>();
public static void getRequest(Method method, Callback callback) {
getRequest(method, callback, null);
}
public static void getRequest(Method method, Callback callback, FormBody formBody) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder();
if (method == Method.GET && formBody != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < formBody.size(); i++) {
sb.append("&").append(formBody.name(i)).append("=").append(formBody.value(i));
}
builder = builder.url(BuildConfig.API_HOST + getUrl() + "?" + sb.substring(1)).method(method.name(), null);
} else {
builder = builder.url(BuildConfig.API_HOST + getUrl()).method(method.name(), formBody);
}
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(callback);
}
public static void getRequest(Callback callback, RequestBody body) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder().url(BuildConfig.API_HOST + getUrl()).method(Method.POST.name(), body);
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(callback);
}
public static void getRequest(Callback callback, String url) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder().url(BuildConfig.API_HOST + url).method(Method.GET.name(), null);
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(callback);
}
//关闭弹窗
private static AlertDialog.Builder getBuilder(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.debug_title, null);
ImageView imageView = view.findViewById(R.id.close);
imageView.setOnClickListener(v -> {
View confirm = View.inflate(context, R.layout.debug_alert, null);
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setView(confirm);
final AlertDialog alertDialog = dialog.create();
confirm.findViewById(R.id.yes).setOnClickListener(v1 -> System.exit(0));
confirm.findViewById(R.id.no).setOnClickListener(v12 -> alertDialog.dismiss());
alertDialog.show();
});
builder.setCustomTitle(view);
return builder;
}
//检查服务端连接
public static void checkServer(final Context context, MutableLiveData<Boolean> bool) {
if (Patterns.WEB_URL.matcher(BuildConfig.API_HOST).matches()) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder().url(BuildConfig.API_HOST);
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
bool.postValue(false);
if (BuildConfig.DEBUG) {
Looper.prepare();
AlertDialog.Builder builder = getBuilder(context);
ConstraintLayout constraintLayout = (ConstraintLayout) View.inflate(context, R.layout.debug, null);
TextView buildType = constraintLayout.findViewById(R.id.build_type);
buildType.setText(context.getString(R.string.build_type, BuildConfig.BUILD_TYPE));
TextView url = constraintLayout.findViewById(R.id.url);
url.setText(context.getString(R.string.server_host, BuildConfig.API_HOST));
TextView detailError = constraintLayout.findViewById(R.id.detailError);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
detailError.setText(stringWriter.toString());
Button openUrl = constraintLayout.findViewById(R.id.open_url);
TextView error = constraintLayout.findViewById(R.id.error);
LinearLayout linearLayout = constraintLayout.findViewById(R.id.my_layout);
int index = linearLayout.indexOfChild(error);
TextView testPort = new TextView(context);
TextView mode = constraintLayout.findViewById(R.id.mode);
switch (BuildType.valueOf(BuildConfig.BUILD_TYPE)) {
case rap2debug:
testPort.setText(R.string.rap2_error);
mode.setText(context.getString(R.string.debug_mode, BuildType.rap2debug.getName()));
break;
case serverdebug:
testPort.setText(R.string.server_error);
mode.setText(context.getString(R.string.debug_mode, BuildType.serverdebug.getName()));
break;
}
testPort.setSingleLine(false);
testPort.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
testPort.setGravity(error.getGravity());
linearLayout.addView(testPort, index + 1);
openUrl.setOnClickListener(v -> {
//从其他浏览器打开
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri content_url = Uri.parse(BuildConfig.API_HOST);
intent.setData(content_url);
Activity activity = (Activity) context;
activity.startActivity(Intent.createChooser(intent, context.getString(R.string.choose_browser)));
});
builder.setView(constraintLayout);
builder.show();
Looper.loop();
}
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) {
bool.postValue(true);
}
});
} else {
String msg = "\n";
if (BuildConfig.API_HOST.contains(" ")) {
msg += context.getString(R.string.server_address_error_1);
} else if (BuildConfig.API_HOST.contains(":") || BuildConfig.API_HOST.contains("。")) {
msg += context.getString(R.string.server_address_error_2);
} else if (!BuildConfig.API_HOST.startsWith("http")) {
msg += context.getString(R.string.server_address_error_3);
} else {
msg += context.getString(R.string.server_address_error_4);
}
getBuilder(context).setMessage(context.getString(R.string.server_address_error, BuildConfig.API_HOST) + msg).show();
}
}
public enum Method {
GET,
POST
}
/**
* 获取调用
*/
@NonNull
private static String getUrl() {
HttpRequest httpRequest = null;
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
String className = null;
String methodName = null;
for (int index = 1; index < stack.length; index++) {
if (HttpUtil.class.getName().equals(stack[index - 1].getClassName()) && !HttpUtil.class.getName().equals(stack[index].getClassName())) {
className = stack[index].getClassName();
methodName = stack[index].getMethodName();
break;
}
}
RuntimeException runtimeException = new RuntimeException("未知异常!!!");
if (className != null) {
try {
if (!map.containsKey(className + methodName)) {
Class c = Class.forName(className);
java.lang.reflect.Method[] methods = c.getMethods();
List<java.lang.reflect.Method> matchMethod = new ArrayList<>();
for (java.lang.reflect.Method m : methods) {
if (methodName.equals(m.getName()) && m.getAnnotation(HttpRequest.class) != null) {
matchMethod.add(m);
}
}
if (matchMethod.size() == 1) {
httpRequest = matchMethod.get(0).getAnnotation(HttpRequest.class);
map.put(matchMethod.get(0).getName(), httpRequest);
} else if (matchMethod.size() > 1) {
runtimeException = new RuntimeException(c.getName() + "包含多个方法名为:" + methodName + "的方法!!!");
} else {
runtimeException = new RuntimeException("类:" + c.getName() + "方法:" + methodName + "缺少注解" + HttpRequest.class + ",无法调用" + HttpUtil.class);
}
} else {
httpRequest = map.get(className + methodName);
}
if (httpRequest != null) {
return httpRequest.value();
}
} catch (ClassNotFoundException | RuntimeException e) {
e.printStackTrace();
}
}
throw runtimeException;
}
}