OKHttp get post使用 以及配合gson使用(转ArrayList<T>的方法)

本文详细介绍了OKHttp网络请求库的主要功能与使用方法,包括GET和POST请求的实现,以及如何利用GSON进行数据解析。

OKHttp

官网地址https://square.github.io/okhttp/

简介

0KHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势,其核心主要有路由、连接协议、拦截器、代理、安全性认证、连接池以及网络适配,拦截器主要是指添加,移除或者转换请求或者回应的头部信息

这个库也是square开源的一个网络请求库(okhttp内部依赖okio)。现在已被Google使用在Android源码上了,可见其强大。

关于网络请求库,现在应该还有很多人在使用androi d-async-http。他内部使用的是HttpClient,但是Google在6.0版本里面删除了httpClient 相关API,可见这个库现在有点过时了。

OKHttp主要功能

1、联网请求文本数据
2、大文件下载
3、大文件.上传
4、请求图片

使用

在build.gradle中添加依赖

 implementation "com.squareup.okhttp3:okhttp:4.9.0"

在AndroidManifest.xml中配置联网权限

 <uses-permission android:name="android.permission.INTERNET"/>

在这里插入图片描述

get请求

在官网文档中可看到Get a URL模块里有这么一段代码

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  try (Response response = client.newCall(request).execute()) {
    return response.body().string();
  }
}

这就是get方式访问url的方法 直接复制到自己的代码里即可
注意该方法只能在子线程使用 在主线程使用会直接崩!
需要再创建一个子线程调用该GET方法

  MyHandler myHandler = new MyHandler();
        mBtnGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        try {
                            String myURL = get("https://v0.yiketianqi.com/api?version=v61&appid=56962523&appsecret=1aNInold");
                            Message msg = Message.obtain();
                            msg.what = 1;
                            msg.obj = myURL;
                            myHandler.sendMessage(msg);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();

通过get获取到url的数据
在这里插入图片描述

POST请求

同样是官方文档内容

public static final MediaType JSON
    = MediaType.get("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  RequestBody body = RequestBody.create(JSON, json);
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
  try (Response response = client.newCall(request).execute()) {
    return response.body().string();
  }
}

同样需要创建子线程 使用post(URL,json)方法 json可以为空"";

   new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    String myURL = post("https://v0.yiketianqi.com/api?version=v61&appid=56962523&appsecret=1aNInold", "");
                    Message msg = Message.obtain();
                    msg.what = 2;
                    msg.obj = myURL;
                    myHandler.sendMessage(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

也能同样获取到数据

注意 以上两个方法都是同步处理是用的是execute()

 try (Response response = client.newCall(request).execute()) {
    return response.body().string();

异步处理

要使用enqueue方法 重写Callback()

   client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                //如果请求失败
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
				//response请求到的数据
            }
        });

GSON

首先在build.gradle注入依赖(可在github查最新版本https://github.com/google/gson):

implementation 'com.google.code.gson:gson:2.8.6'

在handler的接受数据方法(handleMessage)中创建Gson对象
然后将接受到的json格式数据转化并接收成数据类的对象

Gson gson = new Gson();
WeatherData weatherData = gson.fromJson(data, WeatherData.class);

当要把一个ArrayList类型时

ArrayList<WeatherData> receiveData = gson.fromJson(mMmkv.decodeString("datalist"),  new TypeToken<ArrayList<WeatherData>>() {}.getType());
            

其他更多场景下Gson的使用方法:点击此处跳转

package com.example.kucun2.entity.data; import android.util.Log; import androidx.annotation.NonNull; import com.google.gson.Gson; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import okhttp3.Call; import okhttp3.Callback; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * 支持数据变更自动同步的泛型集合类 * @param <T> 继承自 SynchronizableEntity 的实体类型 */ public class SynchronizedList<T extends SynchronizableEntity> implements List<T> { private final List<T> list = new ArrayList<>(); private final OkHttpClient client = new OkHttpClient(); private static final Gson gson = new Gson(); private static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); private final Class<T> entityClass; // 类型标记 // 添加批量操作模式标志 private boolean batchMode = false; // 属性变更监听器 private final List<PropertyChangeListener<T>> listeners = new ArrayList<>(); public SynchronizedList(Class<T> entityClass) { Type superClass = getClass().getGenericSuperclass(); ParameterizedType type = (ParameterizedType) superClass; Type[] typeArgs = type.getActualTypeArguments(); this.entityClass = (Class<T>) typeArgs[0]; } // 安全的类型方法 private T safeCast(Object o) { if (o != null && entityClass.isInstance(o)) { return entityClass.cast(o); } return null; } public interface PropertyChangeListener<T> { void onPropertyChange(T entity, String propertyName, Object oldValue, Object newValue); } public void addPropertyChangeListener(PropertyChangeListener<T> listener) { listeners.add(listener); } public void removePropertyChangeListener(PropertyChangeListener<T> listener) { listeners.remove(listener); } /** * 同步实体到后端 * @param entity 要同步的实体 */ private void syncEntity(T entity) { if (batchMode) return; String endpoint = entity.getEndpoint("add"); // 从实体类获取API端点 String json = gson.toJson(entity); RequestBody body = RequestBody.create(json, JSON); Request request = new Request.Builder() .url(endpoint) .put(body) // 使用PUT更新实体 .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { Log.e("SynchronizedList", "同步失败: " + entity.getClass().getSimpleName(), e); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (!response.isSuccessful()) { Log.e("SynchronizedList", "同步失败: " + response.code() + " - " + response.message()); } response.close(); } }); } // 添加用于批量操作的方法 public void beginBatch() { this.batchMode = true; } public void endBatch() { this.batchMode = false; // 批量结束后触发一次全量同步 syncAllEntities(); } private void syncAllEntities() { for (T entity : list) { syncEntity(entity); } } /** * 创建代理对象,用于监听属性变更 */ private T createProxy(T original) { if (!entityClass.isInstance(original)) { throw new IllegalArgumentException("Invalid entity type"); } // 这里使用动态代理模式监听setter方法调用 return (T) java.lang.reflect.Proxy.newProxyInstance( original.getClass().getClassLoader(), original.getClass().getInterfaces(), (proxy, method, args) -> { // 只拦截setter方法 if (method.getName().startsWith("set") && args.length == 1) { String propertyName = method.getName().substring(3); propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1); // 获取旧值 Object oldValue = original.getClass() .getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1)) .invoke(original); // 调用原始方法 Object result = method.invoke(original, args); // 触发监听器 for (PropertyChangeListener<T> listener : listeners) { listener.onPropertyChange(original, propertyName, oldValue, args[0]); } // 自动同步到后端 syncEntity(original); return result; } return method.invoke(original, args); } ); } // 以下是List接口的实现 @Override public int size() { return list.size(); } @Override public boolean isEmpty() { return list.isEmpty(); } @Override public boolean contains(Object o) { return list.contains(o); } @NonNull @Override public Iterator<T> iterator() { return list.iterator(); } @NonNull @Override public Object[] toArray() { return list.toArray(); } @NonNull @Override public <T1> T1[] toArray(@NonNull T1[] a) { return list.toArray(a); } @Override public boolean add(T t) { T proxy = createProxy(t); boolean result = list.add(proxy); if (!batchMode) { syncEntity(proxy); } return result; // 添加时创建代理 } @Override public boolean remove(Object o) { T entity = safeCast(o); if (entity != null) { syncEntity((T) entity); // 删除前同步 } return list.remove(o); } @Override public boolean containsAll(@NonNull Collection<?> c) { return list.containsAll(c); } @Override public boolean addAll(@NonNull Collection<? extends T> c) { boolean modified = false; for (T t : c) { modified |= add(t); } return modified; } @Override public boolean addAll(int index, @NonNull Collection<? extends T> c) { for (T t : c) { add(index++, t); } return true; } @Override public boolean removeAll(@NonNull Collection<?> c) { for (Object o : c) { T entity = safeCast(o); if (entity != null) { syncEntity(entity); } } return list.removeAll(c); } @Override public boolean retainAll(@NonNull Collection<?> c) { List<T> toRemove = new ArrayList<>(); for (T t : list) { if (!c.contains(t)) { toRemove.add(t); } } // 使用安全换 for (T entity : toRemove) { syncEntity(entity); } return list.retainAll(c); } @Override public void clear() { for (T t : list) { syncEntity(t); // 清空前同步 } list.clear(); } @Override public T get(int index) { return list.get(index); } @Override public T set(int index, T element) { T old = list.set(index, createProxy(element)); if (old != null) { syncEntity(old); // 替换旧元素前同步 } return old; } @Override public void add(int index, T element) { list.add(index, createProxy(element)); } @Override public T remove(int index) { T removed = list.remove(index); if (removed != null) { syncEntity(removed); // 删除前同步 } return removed; } @Override public int indexOf(Object o) { return list.indexOf(o); } @Override public int lastIndexOf(Object o) { return list.lastIndexOf(o); } @NonNull @Override public ListIterator<T> listIterator() { return list.listIterator(); } @NonNull @Override public ListIterator<T> listIterator(int index) { return list.listIterator(index); } @NonNull @Override public List<T> subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } }package com.example.kucun2.entity.data; import android.content.Context; import android.util.Log; import com.example.kucun2.entity.*; import com.example.kucun2.function.MyAppFnction; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Type; import java.util.*; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class Data { // 数据集合声明(保持原有属性名不变) public static SynchronizedList<Bancai> bancais = new SynchronizedList<>(Bancai.class); public static SynchronizedList<Caizhi> caizhis = new SynchronizedList<>(Caizhi.class); public static SynchronizedList<Mupi> mupis = new SynchronizedList<>(Mupi.class); public static SynchronizedList<Chanpin> chanpins = new SynchronizedList<>(Chanpin.class); public static SynchronizedList<Chanpin_Zujian> chanpinZujians = new SynchronizedList<>(Chanpin_Zujian.class); public static SynchronizedList<Dingdan> dingdans = new SynchronizedList<>(Dingdan.class); public static SynchronizedList<Dingdan_Chanpin> dingdanChanpins = new SynchronizedList<>(Dingdan_Chanpin.class); public static SynchronizedList<Dingdan_Bancai> dingdanBancais = new SynchronizedList<>(Dingdan_Bancai.class); public static SynchronizedList<Kucun> kucuns = new SynchronizedList<>(Kucun.class); public static SynchronizedList<Zujian> zujians = new SynchronizedList<>(Zujian.class); public static SynchronizedList<User> users = new SynchronizedList<>(User.class); public static SynchronizedList<Jinhuo> jinhuoList = new SynchronizedList<>(Jinhuo.class); private static final Gson gson = new Gson(); private static final OkHttpClient client = new OkHttpClient(); private static final String TAG = "DataLoader"; // 加载所有数据的方法 public static void loadAllData(Context context, LoadDataCallback callback) { // 开始批量模式 for (SynchronizedList<?> list : getAllSyncLists()) { list.beginBatch(); } String url = MyAppFnction.getStringResource("String", "url") + MyAppFnction.getStringResource("String", "url_all"); Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "Failed to load data", e); if (callback != null) callback.onFailure(); } @Override public void onResponse(Call call, Response response) throws IOException { parseAndAssignData(response.body().string(), context); // 结束批量模式(会触发一次全量同步) for (SynchronizedList<?> list : getAllSyncLists()) { list.endBatch(); } if (callback != null) callback.onSuccess(); } }); } // 获取所有同步列表的方法 private static List<SynchronizedList<?>> getAllSyncLists() { return Arrays.asList(bancais, caizhis, mupis, chanpins, chanpinZujians, dingdans, dingdanChanpins, dingdanBancais, kucuns, zujians, users, jinhuoList); } // 解析并赋值数据 private static void parseAndAssignData(String jsonData, Context context, LoadDataCallback callback) { // 创建包含所有数据类型的TypeToken Type informationType = new TypeToken<Information<AllDataResponse>>(){}.getType(); Information<AllDataResponse> information = gson.fromJson(jsonData, informationType); if (information == null || information.getData() == null || information.getStatus() != 200) { Log.e(TAG, "Invalid response data"); if (callback != null) callback.onFailure(); return; } AllDataResponse allData = information.getData(); // 赋值到对应的列表(使用安全方法保持已有引用) updateList(bancais, allData.bancais); updateList(caizhis, allData.caizhis); updateList(mupis, allData.mupis); updateList(chanpins, allData.chanpins); updateList(chanpinZujians, allData.chanpin_zujians); updateList(dingdans, allData.dingdans); updateList(dingdanChanpins, allData.dingdan_chanpins); updateList(dingdanBancais, allData.dingdan_bancais); updateList(kucuns, allData.kucuns); updateList(zujians, allData.zujians); updateList(users, allData.users); updateList(jinhuoList, allData.jinhuos); resolveReferences(); if (callback != null) callback.onSuccess(); } // 更新列表内容但保持对象引用不变 private static <T> void updateList(List<T> existingList, List<T> newList) { if (newList == null) return; existingList.clear(); for (T item : newList) { existingList.add(item); // 会被包装成代理对象 } } // 解析对象间的引用关系(使用ID关联) private static void resolveReferences() { // 创建ID到对象的映射 Map<Integer, Bancai> bancaiMap = createIdMap(bancais); Map<Integer, Caizhi> caizhiMap = createIdMap(caizhis); Map<Integer, Mupi> mupiMap = createIdMap(mupis); Map<Integer, Chanpin> chanpinMap = createIdMap(chanpins); Map<Integer, Zujian> zujianMap = createIdMap(zujians); Map<Integer, Dingdan> dingdanMap = createIdMap(dingdans); Map<Integer, Kucun> kucunMap = createIdMap(kucuns); // 解析Bancai引用 for (Bancai banca : bancais) { Bancai bancai = bancais.getOriginal(banca); if (bancai.getCaizhi() != null) { bancai.setCaizhi(caizhiMap.get(bancai.getCaizhi().getId())); } if (bancai.getMupi1() != null) { bancai.setMupi1(mupiMap.get(bancai.getMupi1().getId())); } if (bancai.getMupi2() != null) { bancai.setMupi2(mupiMap.get(bancai.getMupi2().getId())); } } // 解析Kucun引用 for (Kucun kucu : kucuns) { Kucun kucun = kucuns.getOriginal(kucu); if (kucun.getBancai() != null) { kucun.setBancai(bancaiMap.get(kucun.getBancai().getId())); } } // 解析订单相关的嵌套对象 for (Dingdan_Chanpin dca : dingdanChanpins) { Dingdan_Chanpin dc = dingdanChanpins.getOriginal(dca); if (dc.getDingdan() != null) { dc.setDingdan(dingdanMap.get(dc.getDingdan().getId())); } if (dc.getChanpin() != null) { dc.setChanpin(chanpinMap.get(dc.getChanpin().getId())); } } // 解析产品相关的嵌套对象 for (Chanpin_Zujian czz : chanpinZujians) { Chanpin_Zujian cz = chanpinZujians.getOriginal(czz); if (cz.getChanpin() != null) { cz.setChanpin(chanpinMap.get(cz.getChanpin().getId())); } if (cz.getZujian() != null) { cz.setZujian(zujianMap.get(cz.getZujian().getId())); } if (cz.getBancai() != null) { cz.setBancai(bancaiMap.get(cz.getBancai().getId())); } } // 解析库存关联 for (Kucun ks : kucuns) { Kucun k = kucuns.getOriginal(ks); if (k.getBancai() != null) { k.setBancai(bancaiMap.get(k.getBancai().getId())); } } } // 添加方法来获取原始对象 @SuppressWarnings("unchecked") public T getOriginal(T proxy) { if (proxy instanceof java.lang.reflect.Proxy) { java.lang.reflect.InvocationHandler handler = java.lang.reflect.Proxy.getInvocationHandler(proxy); if (handler instanceof EntityProxyHandler) { return ((EntityProxyHandler<T>) handler).getOriginal(); } } return proxy; } // 创建ID到对象的映射 private static <T extends EntityClassGrassrootsid> Map<Integer, T> createIdMap(List<T> list) { Map<Integer, T> map = new HashMap<>(); for (T item : list) { map.put(item.getId(), item); } return map; } // 回调接口 public interface LoadDataCallback { void onSuccess(); void onFailure(); } // 内部类用于解析JSON响应 public static class AllDataResponse { public List<Bancai> bancais; public List<Caizhi> caizhis; public List<Mupi> mupis; public List<Chanpin> chanpins; public List<Chanpin_Zujian> chanpin_zujians; public List<Dingdan> dingdans; public List<Dingdan_Chanpin> dingdan_chanpins; public List<Dingdan_Bancai> dingdan_bancais; public List<Kucun> kucuns; public List<Zujian> zujians; public List<User> users; public List<Jinhuo> jinhuos; } }
06-10
package com.example.kucun2.entity.data; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.kucun2.entity.*; import com.example.kucun2.function.MyAppFnction; import com.example.kucun2.function.SafeLogger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; import java.util.stream.Collectors; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class Data { // 数据集合声明(保持原有属性名不变) public static SynchronizedList<Bancai> bancais = new SynchronizedList<>(Bancai.class); public static SynchronizedList<Caizhi> caizhis = new SynchronizedList<>(Caizhi.class); public static SynchronizedList<Mupi> mupis = new SynchronizedList<>(Mupi.class); public static SynchronizedList<Chanpin> chanpins = new SynchronizedList<>(Chanpin.class); public static SynchronizedList<Chanpin_Zujian> chanpin_zujians = new SynchronizedList<>(Chanpin_Zujian.class); public static SynchronizedList<Dingdan> dingdans = new SynchronizedList<>(Dingdan.class); public static SynchronizedList<Dingdan_Chanpin> dingdan_chanpins = new SynchronizedList<>(Dingdan_Chanpin.class); public static SynchronizedList<Dingdan_chanpin_zujian> Dingdan_chanpin_zujians = new SynchronizedList<>(Dingdan_chanpin_zujian.class); public static SynchronizedList<Kucun> kucuns = new SynchronizedList<>(Kucun.class); public static SynchronizedList<Zujian> zujians = new SynchronizedList<>(Zujian.class); public static SynchronizedList<User> users = new SynchronizedList<>(User.class); public static SynchronizedList<Jinhuo> jinhuos = new SynchronizedList<>(Jinhuo.class); public static final Map<Class, SynchronizedList<SynchronizableEntity>> dataCollectionMap = new HashMap<>(); private static final Gson gson = GsonFactory.createWithIdSerialization(); private static OkHttpClient client; private static final String TAG = "DataLoader"; static { // 静态初始化块:在类加载时执行,保证所有静态字段已初始化 try { Field[] fields = Data.class.getDeclaredFields(); for (Field field : fields) { if (SynchronizedList.class.equals(field.getType())) { SynchronizedList<?> list = (SynchronizedList<?>) field.get(null); if (list != null) { dataCollectionMap.put(list.getEntityType(), (SynchronizedList<SynchronizableEntity>) list); } } } } catch (IllegalAccessException e) { throw new RuntimeException("初始化dataCollectionMap失败", e); } } public static void loadAllData(Context context, LoadDataCallback callback) { ensurePreservedObjects(); if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("Data.loadAllData must be called on main thread"); } if (client == null) { client = MyAppFnction.getClient(); } SynchronizableEntity.setSyncEnabled(false); String url = MyAppFnction.getStringResource("string", "url") + MyAppFnction.getStringResource("string", "url_all"); Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "Failed to load data", e); SynchronizableEntity.setSyncEnabled(true); safeCallback(callback, false); } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) { Log.e(TAG, "Unexpected response code: " + response.code()); safeCallback(callback, false); return; } String responseData = response.body().string(); SynchronizableEntity.setSyncEnabled(true); ensurePreservedObjects(); parseAndAssignData(responseData, context, callback); } }); } // 解析并赋值数据(全面空值处理) private static void parseAndAssignData(String jsonData, Context context, LoadDataCallback callback) { Type informationType = new TypeToken<Information<AllDataResponse>>() {}.getType(); Information<AllDataResponse> information = null; try { information = gson.fromJson(jsonData, informationType); } catch (Exception e) { Log.e(TAG, "JSON解析失败: " + e.getMessage()); safeCallback(callback, false); return; } if (information == null || information.getData() == null || information.getStatus() != 200) { Log.e(TAG, "无效响应数据"); safeCallback(callback, false); return; } AllDataResponse allData = information.getData(); SafeLogger.d("data", "原始数据: " + gson.toJson(allData)); // 安全初始化所有列表(处理空列表) safeInitializeList(allData.bancais); safeInitializeList(allData.caizhis); safeInitializeList(allData.mupis); safeInitializeList(allData.chanpins); safeInitializeList(allData.chanpin_zujians); safeInitializeList(allData.dingdans); safeInitializeList(allData.dingdan_chanpins); safeInitializeList(allData.Dingdan_chanpin_zujians); safeInitializeList(allData.kucuns); safeInitializeList(allData.zujians); safeInitializeList(allData.users); safeInitializeList(allData.jinhuos); // 过滤掉所有列表中的空值 allData.bancais = filterNulls(allData.bancais); allData.caizhis = filterNulls(allData.caizhis); allData.mupis = filterNulls(allData.mupis); allData.chanpins = filterNulls(allData.chanpins); allData.chanpin_zujians = filterNulls(allData.chanpin_zujians); allData.dingdans = filterNulls(allData.dingdans); allData.dingdan_chanpins = filterNulls(allData.dingdan_chanpins); allData.Dingdan_chanpin_zujians = filterNulls(allData.Dingdan_chanpin_zujians); allData.kucuns = filterNulls(allData.kucuns); allData.zujians = filterNulls(allData.zujians); allData.users = filterNulls(allData.users); allData.jinhuos = filterNulls(allData.jinhuos); // 更新列表(保留预置对象) updateList(bancais, allData.bancais); updateList(caizhis, allData.caizhis); updateList(mupis, allData.mupis); updateList(chanpins, allData.chanpins); updateList(chanpin_zujians, allData.chanpin_zujians); updateList(dingdans, allData.dingdans); updateList(dingdan_chanpins, allData.dingdan_chanpins); updateList(Dingdan_chanpin_zujians, allData.Dingdan_chanpin_zujians); updateList(kucuns, allData.kucuns); updateList(zujians, allData.zujians); updateList(users, allData.users); updateList(jinhuos, allData.jinhuos); SynchronizableEntity.setSyncEnabled(false); // 自动关联实体(全面空值防护) automaticAssociation(); // 设置所有实体状态 setAllEntitiesState(SynchronizableEntity.SyncState.MODIFIED); ensurePreservedObjects(); SynchronizableEntity.setSyncEnabled(true); safeCallback(callback, true); } // 安全回调方法 public static void safeCallback(LoadDataCallback callback, boolean success) { new Handler(Looper.getMainLooper()).post(() -> { if (callback != null) { if (success) { callback.onSuccess(); } else { callback.onFailure(); } } }); } // 更新列表内容但保持对象引用不变(空值防护) private static <T extends SynchronizableEntity> void updateList(List<T> existingList, List<T> newList) { if (newList == null) return; // 创建临时列表保留预置对象 List<T> preservedObjects = new ArrayList<>(); for (T item : existingList) { if (item != null && item.isPreservedObject()) { preservedObjects.add(item); } } // 清除原有列表并添加保留对象 existingList.clear(); existingList.addAll(preservedObjects); // 添加新数据,跳过空值和无效ID for (T newItem : newList) { if (newItem != null && newItem.getId() != null && newItem.getId() != -1) { existingList.add(newItem); } } } // 添加确保预置对象存在的方法(空值防护) private static void ensurePreservedObjects() { if (!containsPreservedObject(bancais)) bancais.add(createInstance(Bancai.class)); if (!containsPreservedObject(caizhis)) caizhis.add(createInstance(Caizhi.class)); if (!containsPreservedObject(mupis)) mupis.add(createInstance(Mupi.class)); if (!containsPreservedObject(chanpins)) chanpins.add(createInstance(Chanpin.class)); if (!containsPreservedObject(chanpin_zujians)) chanpin_zujians.add(createInstance(Chanpin_Zujian.class)); if (!containsPreservedObject(dingdans)) dingdans.add(createInstance(Dingdan.class)); if (!containsPreservedObject(kucuns)) kucuns.add(createInstance(Kucun.class)); if (!containsPreservedObject(zujians)) zujians.add(createInstance(Zujian.class)); if (!containsPreservedObject(Dingdan_chanpin_zujians)) Dingdan_chanpin_zujians.add(createInstance(Dingdan_chanpin_zujian.class)); if (!containsPreservedObject(dingdan_chanpins)) dingdan_chanpins.add(createInstance(Dingdan_Chanpin.class)); if (!containsPreservedObject(jinhuos)) jinhuos.add(createInstance(Jinhuo.class)); if (!containsPreservedObject(users)) users.add(createInstance(User.class)); automaticAssociation(); } // 检查列表是否包含预置对象 private static <T extends SynchronizableEntity> boolean containsPreservedObject(List<T> list) { for (T item : list) { if (item != null && item.isPreservedObject()) { return true; } } return false; } // 自动关联实体(全面空值防护) private static void automaticAssociation() { try { for (Class t : dataCollectionMap.keySet()) { setDefaultAssociation(Objects.requireNonNull(dataCollectionMap.get(t))); } } catch (IllegalAccessException | ClassNotFoundException e) { Log.e(TAG, "自动关联失败", e); } } /** * 自动关联实体(加强空值处理) */ private static <T extends SynchronizableEntity> void setDefaultAssociation(SynchronizedList<T> list) throws IllegalAccessException, ClassNotFoundException { for (T t : list) { if (t == null) continue; // 跳过空对象 Class clazz = t.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); Class fieldType = f.getType(); // 处理实体引用字段 if (SynchronizableEntity.class.isAssignableFrom(fieldType)) { SynchronizableEntity currentValue = (SynchronizableEntity) f.get(t); // 处理空值或无效ID if (t.getId() < 0 || currentValue == null || currentValue.getId() == null) { // 设置为对应类型的预置对象 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(fieldType); if (targetList != null && !targetList.isEmpty()) { f.set(t, targetList.stream() .filter(item -> item.isPreservedObject()) .findFirst() .orElse(null)); } } else { // 查找匹配的实体 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(fieldType); if (targetList != null) { SynchronizableEntity found = targetList.stream() .filter(item -> currentValue.getId().equals(item.getId())) .findFirst() .orElse(null); // 如果找不到,使用预置对象作为回退 f.set(t, found != null ? found : targetList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } } // 处理列表字段 else if (List.class.isAssignableFrom(fieldType)) { Type genericType = f.getGenericType(); if (genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; Type[] types = pt.getActualTypeArguments(); if (types.length > 0) { Class itemType = Class.forName(types[0].getTypeName()); if (SynchronizableEntity.class.isAssignableFrom(itemType)) { List<SynchronizableEntity> currentList = (List<SynchronizableEntity>) f.get(t); if (currentList == null) { currentList = new ArrayList<>(); f.set(t, currentList); } // 过滤掉空值 currentList.removeAll(Collections.singleton(null)); // 处理空列表或无效ID if (currentList.isEmpty() || t.getId() < 0) { SynchronizedList<SynchronizableEntity> sourceList = dataCollectionMap.get(itemType); if (sourceList != null && !sourceList.isEmpty()) { currentList.add(sourceList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } else { // 更新列表中的引用 SynchronizedList<SynchronizableEntity> sourceList = dataCollectionMap.get(itemType); if (sourceList != null) { for (int i = 0; i < currentList.size(); i++) { SynchronizableEntity item = currentList.get(i); if (item == null) continue; SynchronizableEntity found = sourceList.stream() .filter(e -> e.getId().equals(item.getId())) .findFirst() .orElse(null); // 如果找不到,使用预置对象作为回退 currentList.set(i, found != null ? found : sourceList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } } } } } } // 处理基本类型字段 else { Object value = f.get(t); if (value == null) { // 设置类型安全的默认值 if (String.class.equals(fieldType)) { f.set(t, "无"); } else if (Integer.class.equals(fieldType) || int.class.equals(fieldType)) { f.set(t, -1); } else if (Double.class.equals(fieldType) || double.class.equals(fieldType)) { f.set(t, -1.0); } else if (Boolean.class.equals(fieldType) || boolean.class.equals(fieldType)) { f.set(t, false); } else if (Date.class.equals(fieldType)) { f.set(t, new Date()); } } } } } } /** * 根据传入的Class对象创建对应类型的实例(加强空值防护) */ public static <T> T createInstance(Class<T> clazz) { try { T instance = clazz.getDeclaredConstructor().newInstance(); // 设置默认值 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); Class<?> type = field.getType(); if (type == String.class) { field.set(instance, "无"); } else if (type == Integer.class || type == int.class) { field.set(instance, -1); } else if (type == Double.class || type == double.class) { field.set(instance, -1.0); } else if (type == Boolean.class || type == boolean.class) { field.set(instance, false); } else if (type == Date.class) { field.set(instance, new Date()); } else if (SynchronizableEntity.class.isAssignableFrom(type)) { // 设置为对应类型的预置对象 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(type); if (targetList != null && !targetList.isEmpty()) { field.set(instance, targetList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } else if (List.class.isAssignableFrom(type)) { // 初始化为空列表 field.set(instance, new ArrayList<>()); } } // 设置特殊字段 clazz.getMethod("setId", Integer.class).invoke(instance, -1); clazz.getMethod("setState", SynchronizableEntity.SyncState.class) .invoke(instance, SynchronizableEntity.SyncState.PRESERVED); return instance; } catch (Exception e) { Log.e("Data", "创建实例失败: " + clazz.getName(), e); return createSafeFallback(clazz); } } // 安全回退创建 private static <T> T createSafeFallback(Class<T> clazz) { try { return clazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { throw new RuntimeException("创建回退实例失败", ex); } } // 辅助方法:确保列表不为null private static <T> void safeInitializeList(List<T> list) { if (list == null) { list = new ArrayList<>(); } } // 辅助方法:过滤列表中的空值 private static <T> List<T> filterNulls(List<T> list) { if (list == null) return new ArrayList<>(); return list.stream() .filter(Objects::nonNull) .collect(Collectors.toList()); } // 回调接口 public interface LoadDataCallback { void onSuccess(); void onFailure(); } // 内部类用于解析JSON响应 public static class AllDataResponse { public List<Bancai> bancais; public List<Caizhi> caizhis; public List<Mupi> mupis; public List<Chanpin> chanpins; public List<Chanpin_Zujian> chanpin_zujians; public List<Dingdan> dingdans; public List<Dingdan_Chanpin> dingdan_chanpins; public List<Dingdan_chanpin_zujian> Dingdan_chanpin_zujians; public List<Kucun> kucuns; public List<Zujian> zujians; public List<User> users; public List<Jinhuo> jinhuos; } // 新增方法:设置所有实体状态 private static void setAllEntitiesState(SynchronizableEntity.SyncState state) { setListState(bancais, state); setListState(caizhis, state); setListState(mupis, state); setListState(Dingdan_chanpin_zujians, state); setListState(dingdans, state); setListState(chanpins, state); setListState(chanpin_zujians, state); setListState(zujians, state); setListState(jinhuos, state); setListState(kucuns, state); setListState(users, state); } private static <T extends SynchronizableEntity> void setListState(List<T> list, SynchronizableEntity.SyncState state) { for (T entity : list) { if (entity != null) { entity.setState(state); } } } }结构简化加入详细注释
最新发布
06-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值