将okhttp请求以及gson处理数据封装成单例模式的util类并设置接口回调 使用map拼接url

该博客介绍了如何利用OkHttp库进行网络GET请求,并在请求完成后通过`runOnUiThread`方法在主线程中更新UI,避免了线程同步问题。示例代码展示了如何创建单例的`RequestUtil`类,发送请求并处理成功或失败的回调。在回调中,实现了错误处理和数据解析,然后将数据传递给接口方法进行UI更新。

好处:方便以后调用其中的方法 同时可以不使用handler直接使用 activity.runOnUiThread(new Runnable()…方法进行线程跳转


public class RequestUtil<T> {
    private OkHttpClient client = new OkHttpClient();
    private static RequestUtil requestUtil;
    private final String HOST = "https://v0.yiketianqi.com/api";

    private RequestUtil() {
    }

    // 使用okhttp
    public static RequestUtil getInstance() {
        if (requestUtil == null) {
            requestUtil = new RequestUtil();
        }
        return requestUtil;
    }

    public void sendGet(Class<T> cla, Activity activity, Map<String, Object> params, OnRequestCallback<T> onRequestCallback) {
        // 拼接url
        StringBuilder urlBuilder = new StringBuilder(HOST)
                .append("?")
                .append("version").append("=").append("v62");
        if (params != null && !params.isEmpty()) {
            for (Map.Entry entry : params.entrySet()) {
                // "https://v0.yiketianqi.com/api?version=v62&appid=56962523&appsecret=1aNInold"
                urlBuilder.append("&")
                        .append(entry.getKey())
                        .append("=")
                        .append(entry.getValue());
            }
        }
        Request request = new Request.Builder()
                .url(urlBuilder.toString())
                .build();
        // 采用异步方法
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
                // 跳会到主线程
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        handleError(e.getMessage());
                        if (onRequestCallback != null) {
                            // 执行接口的请求失败方法
                            onRequestCallback.onFailed("");
                        }
                    }
                });
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                // 请求成功的情况下
                String dataStr = response.body().string(); // 接收请求的json数据 注意不能使用toString()会报错
                Gson gson = new Gson();

                // 得到的T类型data
                T data = gson.fromJson(dataStr, cla);
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (response.code() != 200) {
                            if (onRequestCallback != null) {
                                onRequestCallback.onFailed("request error, code = " + response.code());
                            }
                        }

                        if (onRequestCallback != null) {
                            onRequestCallback.onSuccess(data);
                        }
                    }
                });
            }
        });
    }


    private void handleError(String errorMsg) {
        Log.i(getClass().getSimpleName(), "errorMsg = " + errorMsg);
    }

    public interface OnRequestCallback<T> {
        void onSuccess(T data);

        void onFailed(String error);
    }
}

调用该方法:可以直接在接口方法内更新UI


         Map<String,Object> urlMap = new HashMap<String, Object>();
        urlMap.put("appid","56962523");
        urlMap.put("appsecret","1aNInold");


        RequestUtil.getInstance().sendGet(WeatherData.class, this, urlMap, new RequestUtil.OnRequestCallback<WeatherData>() {

            @Override
            public void onSuccess(WeatherData data) {
                if (data!=null&&realTimeTemperatureAdapter!=null){
                    WeatherData weatherData = data;
                    mTvCity.setText(weatherData.city);
                    mTvTem.setText(weatherData.tem);
                    mTvTem1.setText(weatherData.tem1);
                    mTvTem2.setText(weatherData.tem2);
                    mTvWea.setText(weatherData.wea);
                    mTvAir.setText(weatherData.air_level);
                    mTvCountry.setText(weatherData.country);
                    mTvDate.setText(weatherData.date);
                    hours = weatherData.hours;
                    realTimeTemperatureAdapter.updata(hours);
                }
            }

            @Override
            public void onFailed(String error) {

            }
        });
package com.example.kucun2.entity.data; import android.util.Log; import com.example.kucun2.function.MyAppFunction; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 可同步实体基 * 提供实体到服务端的同步功能,包含自动重试机制和线程管理 */ public abstract class SynchronizableEntity implements EntityClassGrassrootsid { private static final String TAG = "SynchronizableEntity"; // 双重缓存结构:外层缓存名,内层缓存字段名->Field对象 private static final Map<Class<?>, Map<String, Field>> CLASS_FIELD_CACHE = new HashMap<>(); // 网络请求线程池(静态共享) private static final ExecutorService NETWORK_EXECUTOR = Executors.newFixedThreadPool(4); /** * 获取指定型操作的端点URL * * @param type 操作型(如"create", "update", "delete"等) * @return 完整的端点URL路径 * * @apiNote 该方法通过资源键名拼接规则查找对应的URL资源 * @example 对于Product的create操作,查找键为:"url_create_product" */ public String getEndpoint(String type) { // 构建资源键名:url_操作型_名小写 String key = "url_" + type + "_" + this.getClass().getSimpleName().toLowerCase(); return MyAppFunction.getStringResource("string", key); } //================ 核心同步方法 ================// /** * 同步实体到服务端(公开接口) * * @param type 操作型(如"create", "update"等) * @param callback 同步结果回调接口 * * @implNote 内部调用私有方法实现带重试机制的同步 * @see #sync(String, SyncCallback, int) */ public void sync(String type, SyncCallback callback) { sync(type, callback, 0); // 初始重试次数为0 } private <T extends SynchronizableEntity> ApiClient.ApiCallback<T> getApiCallback(String type,SyncCallback callback,int retryCount,Class<T > thistype){ return new ApiClient.ApiCallback<T>() { @Override public void onSuccess(T responseData) { handleSyncSuccess(responseData, callback); } @Override public void onError(int statusCode, String error) { handleSyncError(type, statusCode, error, callback, retryCount); } }; } /** * 带重试机制的同步实现(私有方法) * * @param type 操作型 * @param callback 同步结果回调 * @param retryCount 当前重试次数 * * @implSpec 1. 构建完整端点URL * 2. 通过线程池提交网络请求 * 3. 处理成功/失败回调 */ private void sync(String type, SyncCallback callback, int retryCount) { // 构建完整端点URL String baseUrl = MyAppFunction.getStringResource("string", "url"); String endpoint = baseUrl + getEndpoint(type); Log.d(TAG, "同步端点: " + endpoint + ", 重试次数: " + retryCount); // 提交到线程池执行网络请求 NETWORK_EXECUTOR.execute(() -> { ApiClient.postJson(endpoint, this, getApiCallback(type,callback,retryCount,this.getClass())); }); } /** * 处理同步成功结果 * * @param responseData 服务端返回的实体数据 * @param callback 同步结果回调 * * @implNote 1. 更新实体ID * 2. 记录成功日志 * 3. 触发成功回调 */ private void handleSyncSuccess(SynchronizableEntity responseData, SyncCallback callback) { // 更新实体ID(如果服务端返回了新ID) if (responseData != null) { setId(responseData.getId()); Log.i(TAG, "同步成功, 新ID: " + responseData.getId()); } // 触发成功回调 if (callback != null) callback.onSyncSuccess(this); } /** * 处理同步错误(含重试逻辑) * * @param type 操作型 * @param statusCode HTTP状态码(-1表示网络错误) * @param error 错误信息 * @param callback 同步结果回调 * @param retryCount 当前重试次数 * * @implSpec 1. 判断错误是否可重试(网络错误或5xx服务错误) * 2. 满足条件时进行指数退避重试 * 3. 达到最大重试次数后触发失败回调 * * @algorithm 使用指数退避算法:延迟时间 = 1000ms * 2^重试次数 */ private void handleSyncError(String type, int statusCode, String error, SyncCallback callback, int retryCount) { Log.e(TAG, "同步失败: " + error + ", 状态码: " + statusCode); // 判断是否可重试(网络错误或服务端5xx错误) boolean canRetry = statusCode == -1 || (statusCode >= 500 && statusCode < 600); // 满足重试条件(可重试错误且未达到最大重试次数) if (canRetry && retryCount < 3) { // 计算指数退避延迟时间 long delay = (long) (1000 * Math.pow(2, retryCount)); Log.w(TAG, "将在 " + delay + "ms 后重试"); try { // 当前线程休眠指定时间 Thread.sleep(delay); } catch (InterruptedException e) { // 恢复中断状态 Thread.currentThread().interrupt(); } // 递归调用进行重试(重试次数+1) sync(type, callback, retryCount + 1); } else { // 不可重试或达到最大重试次数,触发失败回调 if (callback != null) { String finalError = "同步失败: " + error; if (canRetry) finalError += " (重试失败)"; callback.onSyncFailure(finalError); } } } // 线程安全的对象复制方法 public void updateFrom(Object source) { if ( source == null) return; Class<?> targetClass = this.getClass(); Class<?> sourceClass = source.getClass(); // 获取或创建字段缓存 Map<String, Field> targetFields = getOrCreateFieldCache(targetClass); Map<String, Field> sourceFields = getOrCreateFieldCache(sourceClass); // 遍历源对象字段 for (Map.Entry<String, Field> entry : sourceFields.entrySet()) { String fieldName = entry.getKey(); Field sourceField = entry.getValue(); // 查找目标对象对应字段 Field targetField = targetFields.get(fieldName); if (targetField != null) { // 型兼容性检查 if (isCompatibleTypes(sourceField.getType(), targetField.getType())) { try { // 复制字段值 Object value = sourceField.get(source); targetField.set(this, value); } catch (IllegalAccessException e) { // 处理异常,记录日志 } } } } } // 获取或创建的字段缓存 private static Map<String, Field> getOrCreateFieldCache(Class<?> clazz) { // 双重检查锁确保线程安全 if (!CLASS_FIELD_CACHE.containsKey(clazz)) { synchronized (clazz) { if (!CLASS_FIELD_CACHE.containsKey(clazz)) { Map<String, Field> fieldMap = new HashMap<>(); // 递归获取所有字段(包括父) for (Class<?> current = clazz; current != null; current = current.getSuperclass()) { for (Field field : current.getDeclaredFields()) { field.setAccessible(true); // 突破访问限制 fieldMap.put(field.getName(), field); } } CLASS_FIELD_CACHE.put(clazz, fieldMap); } } } return CLASS_FIELD_CACHE.get(clazz); } // 型兼容性检查(支持自动装箱/拆箱) private static boolean isCompatibleTypes(Class<?> sourceType, Class<?> targetType) { // 处理基本型和包装的兼容性 if (sourceType.isPrimitive()) { sourceType = primitiveToWrapper(sourceType); } if (targetType.isPrimitive()) { targetType = primitiveToWrapper(targetType); } return targetType.isAssignableFrom(sourceType); } // 基本型转包装 private static Class<?> primitiveToWrapper(Class<?> primitiveType) { if (boolean.class.equals(primitiveType)) return Boolean.class; if (byte.class.equals(primitiveType)) return Byte.class; if (char.class.equals(primitiveType)) return Character.class; if (double.class.equals(primitiveType)) return Double.class; if (float.class.equals(primitiveType)) return Float.class; if (int.class.equals(primitiveType)) return Integer.class; if (long.class.equals(primitiveType)) return Long.class; if (short.class.equals(primitiveType)) return Short.class; if (void.class.equals(primitiveType)) return Void.class; return primitiveType; } //================ 回调接口 ================// /** * 同步操作回调接口 * * @implNote 使用方需实现此接口处理同步结果 */ public interface SyncCallback { /** * 同步成功回调 * * @param entity 同步后的实体对象(已更新ID) */ void onSyncSuccess(SynchronizableEntity entity); /** * 同步失败回调 * * @param error 失败原因描述 */ void onSyncFailure(String error); } } package com.example.kucun2.entity.data; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.kucun2.entity.Information; import com.example.kucun2.entity.User; import com.example.kucun2.function.MyAppFunction; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import okhttp3.*; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Map; /** * 重构版API客户端 - 更灵活的处理 * 主要改进: * 1. 分离请求参数型和响应型 * 2. 支持多种请求方法(GET/POST/PUT/DELETE) * 3. 支持表单和JSON两种请求格式 * 4. 自动推导响应型 * 5. 统一的请求执行流程 */ public class ApiClient { private static final Gson gson = GsonFactory.createGson(); private static final String TAG = "ApiClient"; private static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); private static final int MAX_RETRY = 3; private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); // ====================== 核心请求方法 ====================== /** * 执行API请求(核心方法) * @param request 构建好的OkHttp请求 * @param responseType 期望的响应型 * @param callback 回调接口 * @param <R> 响应数据型 */ public static <R> void executeRequest(Request request, Type responseType, ApiCallback<R> callback) { OkHttpClient client = MyAppFunction.getClient(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { handleFailure(call, e, callback, 0); } @Override public void onResponse(Call call, Response response) throws IOException { handleResponse(response, responseType, callback); } }); } // ====================== 请求构建方法 ====================== /** * 构建JSON请求 * @param url API地址 * @param method 请求方法("POST", "PUT", "DELETE") * @param requestData 请求数据对象 * @return 构建好的Request对象 */ public static Request buildJsonRequest(String url, String method, Object requestData) { String jsonRequest = ReflectionJsonUtils.toJson(requestData); Log.d(TAG, method + " URL: " + url); Log.d(TAG, "请求数据: " + jsonRequest); RequestBody body = RequestBody.create(JSON, jsonRequest); return new Request.Builder() .url(url) .method(method, body) .build(); } /** * 构建表单请求 * @param url API地址 * @param method 请求方法 * @param formData 表单数据 * @return 构建好的Request对象 */ public static Request buildFormRequest(String url, String method, Map<String, String> formData) { FormBody.Builder builder = new FormBody.Builder(); for (Map.Entry<String, String> entry : formData.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } Log.d(TAG, method + " URL: " + url); Log.d(TAG, "表单数据: " + formData); return new Request.Builder() .url(url) .method(method, builder.build()) .build(); } // ====================== 响应处理方法 ====================== private static <R> void handleResponse(Response response, Type responseType, ApiCallback<R> callback) throws IOException { try (ResponseBody responseBody = response.body()) { if (!response.isSuccessful()) { String error = "HTTP " + response.code() + ": " + response.message(); Log.e(TAG, error); notifyError(callback, response.code(), error); return; } String jsonResponse = responseBody.string(); Log.d(TAG, "服务器响应: " + jsonResponse); // 解析服务端的Information包装 Information<R> wrapper = gson.fromJson(jsonResponse, responseType); if (wrapper != null && wrapper.getStatus() == 200) { notifySuccess(callback, wrapper.getData()); } else { String errorMsg = wrapper != null ? "服务端错误: " + wrapper.getStatus() + " - " + wrapper.getText() : "无效的响应格式"; Log.e(TAG, errorMsg); notifyError(callback, wrapper != null ? wrapper.getStatus() : -1, errorMsg); } } catch (Exception e) { Log.e(TAG, "响应处理异常: " + e.getMessage()); notifyError(callback, -2, "数据处理异常: " + e.getMessage()); } } // ====================== 失败处理与重试 ====================== private static <R> void handleFailure(Call call, IOException e, ApiCallback<R> callback, int retryCount) { if (retryCount < MAX_RETRY) { Log.w(TAG, "请求失败,第" + (retryCount + 1) + "次重试: " + e.getMessage()); MAIN_HANDLER.postDelayed(() -> { call.clone().enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { handleFailure(call, e, callback, retryCount + 1); } @Override public void onResponse(Call call, Response response) throws IOException { handleResponse(response, getResponseType(callback), callback); } }); }, 2000); } else { Log.e(TAG, "最终请求失败: " + e.getMessage()); notifyError(callback, -1, "网络请求失败: " + e.getMessage()); } } // ====================== 处理工具 ====================== /** * 获取响应型(通过回调接口的泛型参数) */ private static <R> Type getResponseType(ApiCallback<R> callback) { if (callback == null) { return new TypeToken<Information<Object>>(){}.getType(); } // 尝试获取泛型型 Type[] genericInterfaces = callback.getClass().getGenericInterfaces(); for (Type type : genericInterfaces) { if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) type; if (pType.getRawType().equals(ApiCallback.class)) { Type dataType = pType.getActualTypeArguments()[0]; return TypeToken.getParameterized(Information.class, dataType).getType(); } } } // 默认返回Object型 Log.w(TAG, "无法确定响应型,使用默认Object型"); return new TypeToken<Information<Object>>(){}.getType(); } // ====================== 回调通知方法 ====================== private static <R> void notifySuccess(ApiCallback<R> callback, R data) { if (callback != null) { MAIN_HANDLER.post(() -> callback.onSuccess(data)); } } private static <R> void notifyError(ApiCallback<R> callback, int code, String error) { if (callback != null) { MAIN_HANDLER.post(() -> callback.onError(code, error)); } } // ====================== 专用API方法 ====================== /** * 执行JSON API请求 * @param url API地址 * @param method 请求方法 * @param requestData 请求数据 * @param callback 回调接口 * @param <T> 请求数据型 * @param <R> 响应数据型 */ public static <T, R> void jsonRequest(String url, String method, T requestData, ApiCallback<R> callback) { Request request = buildJsonRequest(url, method, requestData); executeRequest(request, getResponseType(callback), callback); } /** * 执行表单API请求 * @param url API地址 * @param method 请求方法 * @param formData 表单数据 * @param callback 回调接口 * @param <R> 响应数据型 */ public static <R> void formRequest(String url, String method, Map<String, String> formData, ApiCallback<R> callback) { Request request = buildFormRequest(url, method, formData); executeRequest(request, getResponseType(callback), callback); } // ====================== 便捷方法 ====================== public static <T, R> void postJson(String url, T data, ApiCallback<R> callback) { jsonRequest(url, "POST", data, callback); } public static <T, R> void putJson(String url, T data, ApiCallback<R> callback) { jsonRequest(url, "PUT", data, callback); } public static <T, R> void deleteJson(String url, T data, ApiCallback<R> callback) { jsonRequest(url, "DELETE", data, callback); } public static <R> void get(String url, ApiCallback<R> callback) { Request request = new Request.Builder().url(url).get().build(); executeRequest(request, getResponseType(callback), callback); } // ====================== 登录专用方法 ====================== public static void login(String username, String password, LoginCallback callback) { String url = MyAppFunction.getApiUrl("url_login"); Log.d(TAG, "login: " + url); formRequest(url, "POST", Map.of( "andy", username, "pass", password ), new ApiCallback<User>() { @Override public void onSuccess(User user) { if (callback != null) callback.onSuccess(user); } @Override public void onError(int statusCode, String error) { if (callback != null) callback.onFailure(error); } }); } // ====================== 回调接口定义 ====================== public interface ApiCallback<T> { void onSuccess(T data); void onError(int statusCode, String error); } public interface LoginCallback { void onSuccess(User user); void onFailure(String error); } } getApiCallback方法是否可行
06-26
package com.example.assignment.login; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.widget.Toast; import androidx.annotation.Nullable; import com.example.assignment.MainActivity; import com.example.assignment.databinding.ActivityWelcomeBinding; import com.example.assignment.login.repo.LoginRequestBean; import com.tplink.apps.architecture.BaseMvvmActivity; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.zip.GZIPInputStream; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class WelcomeActivity extends BaseMvvmActivity<ActivityWelcomeBinding> { @Nullable @Override protected ActivityWelcomeBinding bindContentView(@Nullable Bundle bundle) { return ActivityWelcomeBinding.inflate(getLayoutInflater()); } @Override protected void subscribeViewModel(@Nullable Bundle bundle) { //返回登录选择界面 viewBinding.close.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, LoginChooseActivity.class); startActivity(intent); finish(); }); //TODO 账号验证逻辑 //TODO 登录 viewBinding.btnContained.setOnClickListener(v -> { String username = viewBinding.id.getText(); String password = viewBinding.pass.getText(); LoginRequestBean requestBean = new LoginRequestBean(); requestBean.setAppType("TP-Link_aria_Android"); requestBean.setAppVersion("3.8.33"); requestBean.setCloudPassword(password); // 用户输入 requestBean.setCloudUserName(username); // 用户输入 requestBean.setPlatform("Android " + Build.VERSION.RELEASE); requestBean.setRefreshTokenNeeded(false); requestBean.setTerminalMeta("1"); requestBean.setTerminalName(Build.MANUFACTURER + " " + Build.MODEL); requestBean.setTerminalUUID(Settings.Secure.getString( getContentResolver(), Settings.Secure.ANDROID_ID )); // 转换为JSON发送(使用try-catch) try { JSONObject json = requestBean.toJson(); sendLoginRequest(json); } catch (JSONException e) { // 处理异常 e.printStackTrace(); } }); //忘记密码 viewBinding.forgot.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, ResetActivity.class); startActivity(intent); finish(); }); //无账户 跳转注册界面 viewBinding.text2.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, CreateIDActivity.class); startActivity(intent); finish(); }); } private void sendLoginRequest (JSONObject json){ new Thread(() -> { // 使用HttpHolder提供的OkHttpClient单 OkHttpClient client = HttpHolder.getOkHttpClient(); // 构建请求 RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString()); Request request = new Request.Builder() .url("https://n-wap-beta.tplinkcloud.com/api/v2/account/captchaLogin?appName=TP-Link_aria_Android&appVer=3.8.33&netType=wifi&termID=104AF94B6BAF9F6FDC901A2DFFDAD535&ospf=Android%2012&brand=TPLINK&locale=en_US&model=Redmi%20Note%209%20Pro&termName=Redmi%20Note%209%20Pro&termMeta=1") .post(body) .addHeader("Accept-Encoding", "gzip") .addHeader("Connection", "Keep-Alive") .addHeader("User-Agent", "Dalvik/2.1.0 (Linux; U; Android 12; Redmi Note 9 Pro Build/SKQ1.210908.001)") .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { // 注意:OkHttp会自动处理gzip压缩,所以不需要我们手动解压 String responseBody = response.body().string(); JSONObject jsonResponse = new JSONObject(responseBody); handleLoginResponse(jsonResponse); } else { runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "HTTP错误: " + response.code(), Toast.LENGTH_SHORT).show()); } } catch (Exception e) { runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "请求失败: " + e.getMessage(), Toast.LENGTH_LONG).show()); } }).start(); // new Thread(() -> { // HttpURLConnection connection = null; // try { // // 1. 创建URL对象(使用完整URL) // URL url = new URL("https://n-wap-beta.tplinkcloud.com/api/v2/account/captchaLogin" // + "?appName=TP-Link_aria_Android" // + "&appVer=3.8.33" // + "&netType=wifi" // + "&termID=104AF94B6BAF9F6FDC901A2DFFDAD535" // + "&ospf=Android%2012" // + "&brand=TPLINK" // + "&locale=en_US" // + "&model=Redmi%20Note%209%20Pro" // + "&termName=Redmi%20Note%209%20Pro" // + "&termMeta=1"); // // // 2. 打开HTTP连接 // connection = (HttpURLConnection) url.openConnection(); // connection.setRequestMethod("POST"); // connection.setConnectTimeout(15000); // connection.setReadTimeout(15000); // // // 3. 设置请求头(包含所有指定头) // connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // connection.setRequestProperty("Accept-Encoding", "gzip"); // connection.setRequestProperty("Connection", "Keep-Alive"); // connection.setRequestProperty("User-Agent", "Dalvik/2.1.0 (Linux; U; Android 12; Redmi Note 9 Pro Build/SKQ1.210908.001)"); // // // 4. 启用输出流写入JSON数据 // connection.setDoOutput(true); // try (OutputStream os = connection.getOutputStream()) { // byte[] input = json.toString().getBytes(StandardCharsets.UTF_8); // os.write(input, 0, input.length); // } // // // 5. 获取响应码 // int responseCode = connection.getResponseCode(); // if (responseCode == HttpURLConnection.HTTP_OK) { // // 6. 处理Gzip压缩响应 // InputStream is = "gzip".equalsIgnoreCase(connection.getContentEncoding()) // ? new GZIPInputStream(connection.getInputStream()) // : connection.getInputStream(); // // // 7. 读取响应内容 // try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { // StringBuilder response = new StringBuilder(); // String line; // while ((line = reader.readLine()) != null) { // response.append(line); // } // // // 8. 解析JSON响应 // JSONObject jsonResponse = new JSONObject(response.toString()); // handleLoginResponse(jsonResponse); // } // } else { // runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "HTTP错误: " + responseCode, Toast.LENGTH_SHORT).show()); // } // } catch (Exception e) { // runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "请求失败: " + e.getMessage(), Toast.LENGTH_LONG).show()); // } finally { // if (connection != null) connection.disconnect(); // } // }).start(); } // 处理登录响应 private void handleLoginResponse (JSONObject jsonResponse){ runOnUiThread(() -> { try { int errorCode = jsonResponse.optInt("error_code", -1); JSONObject result = jsonResponse.optJSONObject("result"); if (errorCode == 0 && result != null) { String token = result.optString("token", ""); if (!token.isEmpty()) { // 登录成功处理 // saveToken(token); startActivity(new Intent(this, MainActivity.class)); } else { // showError("token获取失败"); Toast.makeText(WelcomeActivity.this, "token获取失败", Toast.LENGTH_LONG).show(); } } else { String errorMsg = result != null ? result.optString("msg", "未知错误") : "响应格式错误"; // showError("登录失败: " + errorCode + " - " + errorMsg); Toast.makeText(WelcomeActivity.this, "登录失败: " + errorCode + " - " + errorMsg, Toast.LENGTH_LONG).show(); } } catch (Exception e) { // showError("响应解析异常: " + e.getMessage()); Toast.makeText(WelcomeActivity.this, "响应解析异常: " + e.getMessage(), Toast.LENGTH_LONG).show(); } }); } private static final String CLOUD_CERT = "-----BEGIN CERTIFICATE-----\n" + "MIIDBzCCAe+gAwIBAgIQT5x0ma7QnINHCQvhnmzR9zANBgkqhkiG9w0BAQsFADAV\n" + "MRMwEQYDVQQDEwp0cC1saW5rLUNBMCAXDTE4MDExOTA4Mjc1MloYDzIwNjgwMTE5\n" + "MDgzNzUyWjAVMRMwEQYDVQQDEwp0cC1saW5rLUNBMIIBIjANBgkqhkiG9w0BAQEF\n" + "AAOCAQ8AMIIBCgKCAQEAuGG8n5zEUN1j5wuvUz4pAIMurhKHbpfUUu+b2acFHKS6\n" + "iU9hNJWvDyhXcihY5Wz6aq9m4D5SZcgW3k31YoNNtrztDjdg2qw7AaX85S99/G0B\n" + "VbIXktrhs34OW19WA/haDwut3dFhLem+gCRRKUXcmuqchZc84dY7JFVfhPcJci4m\n" + "sRjLCFNO0ho9OX+MZwfO4BLaeAqKVoAor6rf4BXVtO0xjYHDKO0fb3AWLLJ4EjGe\n" + "q6YieqPiYlPFEqRm5PrvBXTm0IuQogygyVpK4LHr/K207ZLyV33DxLLbsUgSEJVn\n" + "pZUv/WUujXjlIDgxIvyZZCYiXO3dle2/MEvpmZk6JQIDAQABo1EwTzALBgNVHQ8E\n" + "BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUxu2iBRTsef5iNnsADVhM\n" + "JDQWi6kwEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQELBQADggEBAB52Majd\n" + "+wo3cb5BsTo63z2Psbbyl4ACMUaw68NxUMy61Oihx3mcLzLJqiIZcKePiHskLqLJ\n" + "F7QfT9TqjvizMjFJVgsLuVubUBXKBzqyN+3KKlQci0PO3mH+ObhyaE7BzV+qrS3P\n" + "dVTgsCWFv8DkgLTRudSWxL7VwVoedc7lRz5EroGgJ33nRGCR0ngcW919tLTARDQO\n" + "pULmzulcdWeZgG+0PLX0xjJQIjFEvbOxR1Z+gxMupBz0rWFokmWYrcga8eWiWzjQ\n" + "Ia3/ASBVJ69srV77trWlfLumkChbXk9i64NXBKnce0Jmll0Y9OC1nMPqrbQKnzcn\n" + "dSAA4fejD/qMQn0=\n" + "-----END c-----"; // UI线程执行辅助方法 // private void runOnUiThread (Runnable action){ // new Handler(Looper.getMainLooper()).post(action); // } } 改为retrofit实现应该怎么修改呢 还是用java
最新发布
09-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值