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.Response; public class HttpUtil { private static final Map 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); } //关闭弹窗 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 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 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; } }