package com.example.kucun2.entity.data;
import android.util.Log;
import androidx.annotation.NonNull;
import com.example.kucun2.function.MyAppFnction;
import com.google.gson.Gson;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.*;
import okhttp3.*;
/**
* 支持数据变更自动同步的泛型集合类
* 移除了代理机制,改用基类的事件监听
*/
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 boolean batchMode = false;
// 实体变更监听器
private final EntityChangeListener<T> listener = entity -> {
if (!batchMode) syncEntity(entity);
};
// 直接接受Class参数的构造函数
public SynchronizedList(Class<T> T) {}
// 添加监听器的方法
private void registerListener(T entity) {
if (entity != null) {
entity.addPropertyChangeListener(listener);
}
}
private void unregisterListener(T entity) {
if (entity != null) {
entity.removePropertyChangeListener(listener);
}
}
private String getUrl() {
return MyAppFnction.getStringResource("string", "url");
}
/**
* 同步实体到后端
*/
private static void syncEntity(SynchronizableEntity entity) {
String operation = "update"; // 默认为更新操作
String endpoint = entity.getEndpoint(operation);
String json = gson.toJson(entity);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(getUrl() + 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.close();
}
});
}
// 批量操作方法
public void beginBatch() {
this.batchMode = true;
}
public void endBatch() {
this.batchMode = false;
syncAllEntities();
}
private void syncAllEntities() {
for (T entity : list) {
syncEntity(entity);
}
}
// List接口实现(添加时注册监听器,移除时取消监听)
@Override
public boolean add(T t) {
registerListener(t);
boolean result = list.add(t);
if (!batchMode) syncEntity(t);
return result;
}
@Override
public void add(int index, T element) {
registerListener(element);
list.add(index, element);
if (!batchMode) syncEntity(element);
}
@Override
public boolean remove(Object o) {
if (o instanceof SynchronizableEntity) {
T entity = (T) o;
unregisterListener(entity);
if (!batchMode) syncEntity(entity);
}
return list.remove(o);
}
@Override
public T remove(int index) {
T entity = list.get(index);
if (entity != null) {
unregisterListener(entity);
if (!batchMode) syncEntity(entity);
}
return list.remove(index);
}
@Override
public boolean addAll(@NonNull Collection<? extends T> c) {
for (T t : c) registerListener(t);
return list.addAll(c);
}
@Override
public boolean removeAll(@NonNull Collection<?> c) {
for (Object o : c) {
if (o instanceof SynchronizableEntity) {
unregisterListener((T) o);
}
}
return list.removeAll(c);
}
@Override
public boolean retainAll(@NonNull Collection<?> c) {
return false;
}
@Override
public void clear() {
for (T t : list) {
unregisterListener(t);
if (!batchMode) syncEntity(t);
}
list.clear();
}
@Override
public T get(int index) {
return list.get(index);
}
@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 containsAll(@NonNull Collection<?> c) {
return list.containsAll(c);
}
@Override
public boolean addAll(int index, @NonNull Collection<? extends T> c) {
for (T element : c) {
registerListener(element);
}
boolean result = list.addAll(index, c);
if (!batchMode) {
for (T element : c) {
syncEntity(element);
}
}
return result;
}
@Override
public T set(int index, T element) {
T oldElement = list.set(index, element);
// 取消旧元素的监听
if (oldElement != null) {
unregisterListener(oldElement);
if (!batchMode) syncEntity(oldElement);
}
// 注册新元素的监听
registerListener(element);
if (!batchMode) {
syncEntity(element);
}
return oldElement;
}
@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 new SynchronizedListWrapper(list.subList(fromIndex, toIndex));
}
// 其他List接口方法保持原样...
// [此处省略未修改的List接口方法实现]
/**
* 实体变更监听接口
*/
public interface EntityChangeListener<T> extends PropertyChangeListener {
default void onPropertyChange(T entity, String propertyName, Object oldValue, Object newValue) {
syncEntity((SynchronizableEntity) entity);
}
}
// ==================== 内部辅助类 ====================
private class SynchronizedListWrapper implements List<T> {
private final List<T> wrapped;
public SynchronizedListWrapper(List<T> list) {
this.wrapped = list;
}
@Override
public boolean add(T element) {
registerListener(element);
boolean result = wrapped.add(element);
if (!batchMode) syncEntity(element);
return result;
}
@Override
public void add(int index, T element) {
registerListener(element);
wrapped.add(index, element);
if (!batchMode) syncEntity(element);
}
@Override
public T set(int index, T element) {
T oldElement = wrapped.get(index);
if (oldElement != null) {
unregisterListener(oldElement);
if (!batchMode) syncEntity(oldElement);
}
registerListener(element);
T result = wrapped.set(index, element);
if (!batchMode) syncEntity(element);
return result;
}
@Override
public T remove(int index) {
T element = wrapped.get(index);
if (element != null) {
unregisterListener(element);
if (!batchMode) syncEntity(element);
}
return wrapped.remove(index);
}
@Override
public boolean remove(Object o) {
if (o instanceof SynchronizableEntity) {
T entity = (T) o;
if (wrapped.contains(entity)) {
unregisterListener(entity);
if (!batchMode) syncEntity(entity);
}
}
return wrapped.remove(o);
}
@Override
public boolean addAll(@NonNull Collection<? extends T> c) {
for (T element : c) {
registerListener(element);
}
boolean result = wrapped.addAll(c);
if (!batchMode) {
for (T element : c) {
syncEntity(element);
}
}
return result;
}
@Override
public boolean addAll(int index, @NonNull Collection<? extends T> c) {
for (T element : c) {
registerListener(element);
}
boolean result = wrapped.addAll(index, c);
if (!batchMode) {
for (T element : c) {
syncEntity(element);
}
}
return result;
}
@Override
public boolean removeAll(@NonNull Collection<?> c) {
// 先取消所有要移除元素的监听器
for (Object o : c) {
if (o instanceof SynchronizableEntity) {
T entity = (T) o;
if (wrapped.contains(entity)) {
unregisterListener(entity);
if (!batchMode) syncEntity(entity);
}
}
}
return wrapped.removeAll(c);
}
@Override
public boolean retainAll(@NonNull Collection<?> c) {
// 找出要移除的元素
List<T> toRemove = new ArrayList<>();
for (T element : wrapped) {
if (!c.contains(element)) {
toRemove.add(element);
}
}
// 取消这些元素的监听器
for (T element : toRemove) {
unregisterListener(element);
if (!batchMode) syncEntity(element);
}
return wrapped.retainAll(c);
}
@Override
public void clear() {
// 取消所有元素的监听器
for (T element : wrapped) {
unregisterListener(element);
if (!batchMode) syncEntity(element);
}
wrapped.clear();
}
// ---------------- 以下是非修改方法,直接委托给包装列表 ----------------
@Override
public int size() {
return wrapped.size();
}
@Override
public boolean isEmpty() {
return wrapped.isEmpty();
}
@Override
public boolean contains(Object o) {
return wrapped.contains(o);
}
@NonNull
@Override
public Iterator<T> iterator() {
return wrapped.iterator();
}
@NonNull
@Override
public Object[] toArray() {
return wrapped.toArray();
}
@NonNull
@Override
public <T1> T1[] toArray(@NonNull T1[] a) {
return wrapped.toArray(a);
}
@Override
public boolean containsAll(@NonNull Collection<?> c) {
return wrapped.containsAll(c);
}
@Override
public T get(int index) {
return wrapped.get(index);
}
@Override
public int indexOf(Object o) {
return wrapped.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return wrapped.lastIndexOf(o);
}
@NonNull
@Override
public ListIterator<T> listIterator() {
return wrapped.listIterator();
}
@NonNull
@Override
public ListIterator<T> listIterator(int index) {
return wrapped.listIterator(index);
}
@NonNull
@Override
public List<T> subList(int fromIndex, int toIndex) {
return new SynchronizedListWrapper(wrapped.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.Field;
import java.lang.reflect.Method;
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,callback);
// 结束批量模式(会触发一次全量同步)
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() {
// 创建全局对象映射
Map<Integer, EntityClassGrassrootsid> globalMap = new HashMap<>();
// 填充全局映射表
addToGlobalMap(globalMap, bancais);
addToGlobalMap(globalMap, caizhis);
addToGlobalMap(globalMap, mupis);
addToGlobalMap(globalMap, chanpins);
addToGlobalMap(globalMap, zujians);
addToGlobalMap(globalMap, dingdans);
addToGlobalMap(globalMap, kucuns);
addToGlobalMap(globalMap, users);
// 解析所有实体的引用
resolveListReferences(bancais, globalMap);
resolveListReferences(kucuns, globalMap);
resolveListReferences(dingdanChanpins, globalMap);
resolveListReferences(chanpinZujians, globalMap);
resolveListReferences(dingdanBancais, globalMap);
resolveListReferences(jinhuoList, globalMap);
}
// 添加对象到全局映射表
private static void addToGlobalMap(Map<Integer, EntityClassGrassrootsid> map,
SynchronizedList<?> list) {
for (Object item : list) {
Object original = getOriginalFromList(list, item);
if (original instanceof EntityClassGrassrootsid) {
EntityClassGrassrootsid entity = (EntityClassGrassrootsid) original;
map.put(entity.getId(), entity);
}
}
}
// 解析列表中所有实体的引用
private static void resolveListReferences(SynchronizedList<?> list,
Map<Integer, EntityClassGrassrootsid> globalMap) {
for (Object item : list) {
Object original = getOriginalFromList(list, item);
resolveEntityReferences(original, globalMap);
}
}
// 安全获取原始对象(无需类型转换)
@SuppressWarnings("unchecked")
private static <T> T getOriginalFromList(SynchronizedList<?> list, Object item) {
try {
// 使用反射调用getOriginal方法
Method getOriginal = list.getClass().getMethod("getOriginal", Object.class);
return (T) getOriginal.invoke(list, item);
} catch (Exception e) {
Log.e("Data", "Failed to get original object", e);
return (T) item;
}
}
//解析集合中的引用
private static void resolveCollectionReferences(Collection<?> collection,
Map<Integer, EntityClassGrassrootsid> globalMap) {
for (Object item : collection) {
if (item instanceof EntityClassGrassrootsid) {
EntityClassGrassrootsid ref = (EntityClassGrassrootsid) item;
EntityClassGrassrootsid resolved = globalMap.get(ref.getId());
if (resolved != null && ref.getClass().isInstance(resolved)) {
// 注意:直接替换集合元素需要特殊处理
// 实际项目应考虑使用CopyOnWrite集合或创建新集合
if (collection instanceof List) {
int index = ((List<?>) collection).indexOf(ref);
if (index != -1) {
try {
((List<Object>) collection).set(index, resolved);
} catch (Exception e) {
Log.e("Data", "Failed to update collection", e);
}
}
}
}
}
}
}
// 解析单个实体的引用
private static void resolveEntityReferences(Object entity,
Map<Integer, EntityClassGrassrootsid> globalMap) {
if (entity == null) return;
// 如果是代理对象则获取原始对象
Object target = entity;
if (entity instanceof SynchronizedList.IProxyHandler) {
target = ((SynchronizedList.IProxyHandler) entity).getOriginal();
}
Class<?> clazz = entity.getClass();
for (Field field : clazz.getDeclaredFields()) {
try {
field.setAccessible(true);
// 处理基本类型字段
if (EntityClassGrassrootsid.class.isAssignableFrom(field.getType())) {
EntityClassGrassrootsid ref = (EntityClassGrassrootsid) field.get(entity);
if (ref != null && ref.getId() != null) {
EntityClassGrassrootsid resolved = globalMap.get(ref.getId());
if (resolved != null && field.getType().isInstance(resolved)) {
field.set(entity, resolved);
}
}
}
// 处理集合类型字段
else if (Collection.class.isAssignableFrom(field.getType())) {
Collection<?> collection = (Collection<?>) field.get(entity);
if (collection != null) {
resolveCollectionReferences(collection, globalMap);
}
}
} catch (Exception e) {
Log.e("Data", "Error resolving field: " + field.getName(), e);
}
}
}
// 创建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();
}
private static void resolveFields(Object entity, Map<Integer, EntityClassGrassrootsid> globalMap) {
for (Field field : entity.getClass().getDeclaredFields()) {
if (EntityClassGrassrootsid.class.isAssignableFrom(field.getType())) {
try {
field.setAccessible(true);
EntityClassGrassrootsid ref = (EntityClassGrassrootsid) field.get(entity);
if (ref != null) {
EntityClassGrassrootsid resolved = globalMap.get(ref.getId());
if (resolved != null && field.getType().isAssignableFrom(resolved.getClass())) {
field.set(entity, resolved);
}
}
} catch (Exception e) {
Log.e("Data", "Error resolving reference", e);
}
}
}
}
// 内部类用于解析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;
}
}package com.example.kucun2.entity.data;
import android.util.Log;
import com.example.kucun2.function.MyAppFnction;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;
import java.util.Map;
public abstract class SynchronizableEntity implements EntityClassGrassrootsid {
// 使用标准属性变更支持类
private transient PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
// 属性缓存(可选,用于优化)
private final Map<String, Object> propertyCache = new HashMap<>();
// 添加属性变更监听器
public void addPropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport == null) {
changeSupport = new PropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
// 移除属性变更监听器
public void removePropertyChangeListener(PropertyChangeListener listener) {
if (changeSupport != null) {
changeSupport.removePropertyChangeListener(listener);
}
}
// 触发属性变更通知(子类在setter中调用)
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
if (changeSupport != null && changeSupport.hasListeners(propertyName)) {
// 更新属性缓存(可选)
propertyCache.put(propertyName, newValue);
// 触发变更事件
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}
// 获取属性当前值(可选,用于setter中获取旧值)
protected <T> T getCachedProperty(String propertyName) {
return (T) propertyCache.get(propertyName);
}
// 初始化属性缓存(可选,在构造函数中调用)
protected void initPropertyCache() {
// 初始化所有字段到缓存
for (java.lang.reflect.Field field : getClass().getDeclaredFields()) {
try {
field.setAccessible(true);
propertyCache.put(field.getName(), field.get(this));
} catch (Exception e) {
// 忽略初始化异常
}
}
}
/**
* 添加url
* @param type 操作增删改查
* @return 返回相对url
*/
public String getEndpoint(String type){
//从String.xml获取url
Log.d("getEndpoint", "getEndpoint: "+"url_"+type+"_"+this.getClass().getSimpleName().toLowerCase());
return MyAppFnction.getStringResource("string","url_"+type+"_"+this.getClass().getSimpleName().toLowerCase());
}
public void sync(){
}
}