PropertyChangeListener关联属性的简单介绍

本文介绍JavaBean中关联属性的概念及其实现方式,通过PropertyChangeSupport类管理监听器,实现属性值变化时的通知机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    JavaBean的属性与一般Java程序中所指的属性,或者说与所有面向对象的程序设计语言中对象的属性是一个概念,在程序中的具体体现就是类中的变量。在JavaBean的设计中,按照属性的不同作用又细分为四类:单值属性索引属性关联属性限制属性

  本文主要介绍如何使用PropertyChangeSupport类来支持关联属性事件的触发。

  1.关联属性

  关联属性,也称之为绑定属性。绑定属性会在属性值发生变化时,通知所有相关的监听器。为了实现一个绑定属性,必须实现两个机制。

  1) 无论何时,只要属性的值发生变化,该bean必须发送一个PropertyChange事件给所有已注册的监听器。该变化可能发生在调用set方法时,或者程序的用户做出某种动作时。

  2) 为了使感兴趣的监听器能够进行注册,bean必须实现以下两个方法:

void addPropertyChangeListener(PropertyChangeListener listener);

void removePropertyChangeListener(PropertyChangeListener listener);

  2.使用PropertyChangeSupport管理监听器

  可以通过java.bean包下的PropertyChangeSupport类来管理监听器。要使用这个类,bean必须有一个此类的数据域。

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

  这样就可以将添加和移除监听器的任务交给这个对象。

public void addPropertyChangeListener(PropertyChangeListener listener) {

  changes.addPropertyChangeListener(listener);

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

  changes.removePropertyChangeListener(listener);

}

    当bean的属性发生变化时,使用PropertyChangeSupport对象的firePropertyChange方法,它会将一个事件发送给所有已经注册的监听器。该方法有三个参数:属性的名字、旧的值以及新的值。属性的值必须是对象,如果是简单数据类型,则必须进行包装。

 changes.firePropertyChange("ourString", oldString, newString);

  所有注册的监听器实现PropertyChangeListener接口,该接口中只有一个方法。

public void propertyChange(PropertyChangeEvent e);

  当bean的属性值发生变化时,该方法中的代码就会被触发。可以通过

  e.getOldValue();

  e.getNewValue();

  来得到changes.firePropertyChange("ourString", oldString, newString);中的oldString和newString。

  3.为什么要使用PropertyChangeSupport

  使用这个类管理监听器的好处:

    1)它是线程安全的。如果使用一个循环体来set Bean的属性,则这个类可以保证所有监听器执行触发事件的有序。

  2)这个类支持fire带索引的属性改变事件(详见java.bean.IndexedPropertyChangeEvent)。此时向注册的监听器发送一个

       PropertyChangeEvent的方法为:

void fireIndexedPropertyChange(String PropertyName,int index,Object oldValue,Object newValue);

  4.示例

  MyBoundBean类(具体代码见附件)是一个JavaBean,我们关注它的唯一一个属性ourString的变化情况,它的初始值是Hello。并通过PropertyChange类来管理监听器。注意在set方法中会调用firePropertyChange方法。

MyBoundBean.java
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class MyBoundBean {
  String ourString = "Hello";
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  public void setString(String newString) {
    String oldString = ourString;
    ourString = newString;
    changes.firePropertyChange("ourString", oldString, newString);
  }
  public String getString() {
    return ourString;
  }
  public void addPropertyChangeListener(PropertyChangeListener listener) {
    changes.addPropertyChangeListener(listener);
  }
  public void removePropertyChangeListener(PropertyChangeListener listener) {
    changes.removePropertyChangeListener(listener);
  }
}

Java:在Bean中使用PropertyChangeSupport支持PropertyChangeListeners

 

MyBoundBean b = new MyBoundBean();

public void actionPerformed(ActionEvent e) {
  jButton1.setText(textBox.getText());
  b.setString(textBox.getText());
}

  目标bean的属性一改变(注意,初始值是"Hello"),将会触发propertyChange方法的执行。将文本框的内容设置为目标bean的ourString属性的旧值,同时,将jButton2的test设置成目标bean的ourString属性的新值。

public void propertyChange(PropertyChangeEvent e) {
  if (e.getSource() == b) {
    textBox.setText(e.getOldValue().toString());
    jButton2.setText(e.getNewValue().toString());
  }
}

Java:在Bean中使用PropertyChangeSupport支持PropertyChangeListeners

  如果不实现PropertyChangeListener接口的话,可以使用匿名内部类来达到同样的效果。(具体代码见附件MyCallBound2.java)

MyBoundBean b = new MyBoundBean();

b.addPropertyChangeListener(new PropertyChangeListener() {
  public void propertyChange(PropertyChangeEvent e) {
    // 这样一来,我们就可以用自己定义的名字实现事件
    ourString_propertyChange(e);
  }
});

 

  这样一来,我们就可以用自己定义的名字实现事件。

void ourString_propertyChange(PropertyChangeEvent e) {
  if (e.getSource() == b) {
    textBox.setText(e.getOldValue().toString());
    jButton2.setText(e.getNewValue().toString());
  }
}

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.RefTo; import com.example.kucun2.entity.RefType; import com.example.kucun2.function.MyAppFunction; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** 可同步实体基类 实现实体状态管理、属性变更监听、服务端同步等功能 */ public abstract class SynchronizableEntity implements EntityClassGrassrootsid { private static String TAG=“SynchronizableEntity”; // 实体同步状态枚举 public enum SyncState private SyncState state = SyncState.NEW; private static final int MAX_RETRY = 3; private int retryCount = 0; private static final Map<String, Boolean> syncLocks = new ConcurrentHashMap<>(); private static final ThreadLocal<Set> syncStack = ThreadLocal.withInitial(HashSet::new); // 属性变更支持 private transient PropertyChangeSupport changeSupport; // 属性缓存 private final Map<String, Object> propertyCache = new HashMap<>(); private static boolean syncEnabled = true; // 全局同步开关 //================ 基础方法 ================// /** 判断是否为预保存对象 */ public boolean isPreservedObject() { return this.getId() != null && this.getId() == -1; } /** 设置全局同步开关 */ public static void setSyncEnabled(boolean enabled) { syncEnabled = enabled; } /** 获取/设置实体状态 */ public SyncState getState() { return this.state; } public void setState(SyncState state) { this.state = state; } //================ 属性变更监听 ================// /** 添加属性变更监听器 */ 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); } } // 触发属性变更时自动同步 protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (changeSupport != null && changeSupport.hasListeners(propertyName)) { propertyCache.put(propertyName, newValue); changeSupport.firePropertyChange(propertyName, oldValue, newValue); } // 状态为SYNCED时标记为需要同步 if (state == SyncState.SYNCED) { state = SyncState.MODIFIED; } // 启动同步(非新建实体) if (state != SyncState.NEW && state != SyncState.SYNCING) { scheduleSync(); } } //================ 端点URL生成 ================// /** 获取操作端点URL */ public String getEndpoint(String type) { String key = “url_” + type + “_” + this.getClass().getSimpleName().toLowerCase(); return MyAppFunction.getStringResource(“string”, key); } //================ 核心同步方法 ================// /** 执行同步操作 */ public void sync(SyncCallback callback) { if (!syncEnabled) return; // 检查全局开关 try { switch (this.state) { case NEW: createToServer(callback); break; case MODIFIED: updateToServer(callback); break; case DELETED: deleteFromServer(callback); break; } } catch (Exception e) { Log.e("SyncError", "Sync failed for " + getClass().getSimpleName(), e); } } //================ 服务端操作 ================// /** 创建实体到服务端 */ private void createToServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource(“string”, “url”) + getEndpoint(“add”); Log.d(TAG, "创建端点: " + endpoint); ApiClient.post(endpoint, this, new ApiClient.ApiCallback<SynchronizableEntity>() { @Override public void onSuccess(SynchronizableEntity responseData) { if (responseData != null) { setId(responseData.getId()); } state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } private void updateToServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource(“string”, “url”) + getEndpoint(“update”) + “/” + getId(); ApiClient.put(endpoint, this, new ApiClient.ApiCallback<SynchronizableEntity>() { @Override public void onSuccess(SynchronizableEntity responseData) { state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } private void deleteFromServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource(“string”, “url”) + getEndpoint(“delete”); // 创建删除请求对象(包含ID) ApiClient.delete(endpoint, this, new ApiClient.ApiCallback<Void>() { @Override public void onSuccess(Void data) { state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } // 安排同步任务(防止频繁同步) private void scheduleSync() { String lockKey = this.getClass().getName() + getId(); synchronized (syncLocks) { if (syncLocks.containsKey(lockKey)) return; syncLocks.put(lockKey, true); } new Handler(Looper.getMainLooper()).postDelayed(() -> { syncWithDependencies(null); synchronized (syncLocks) { syncLocks.remove(lockKey); } }, 1000); // 1秒延迟 } /** 带依赖关系的同步方法 根据 @RefTo 注解的依赖关系,确保: 双向关联的反向字段会同步更新 列表关联的所有元素会按顺序同步 单引用实体优先同步 @param callback 同步完成回调 */ public void syncWithDependencies(SyncCallback callback) { // 检测循环依赖 String entityKey = this.getClass().getName() + getId(); Set currentStack = syncStack.get(); if (currentStack.contains(entityKey)) { Log.w(“Sync”, "检测到循环依赖: " + entityKey); if (callback != null) callback.onSyncFailure(“循环依赖”); return; } currentStack.add(entityKey); state = SyncState.SYNCING; try { // 获取所有依赖实体 List dependencies = getDependencies(); if (dependencies.isEmpty()) { syncInternal(callback); return; } // 同步所有依赖实体 AtomicInteger counter = new AtomicInteger(dependencies.size()); for (Dependency dep : dependencies) { dep.entity.syncWithDependencies(new SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { // 处理双向关联的反向字段 if (dep.isBidirectional) { updateReverseField(dep, entity); } if (counter.decrementAndGet() == 0) { syncInternal(callback); } } @Override public void onSyncFailure(String error) { if (callback != null) { callback.onSyncFailure(error); } state = SyncState.MODIFIED; // 重置状态 } }); } } finally { currentStack.remove(entityKey); } } // 更新双向关联的反向字段 private void updateReverseField(Dependency dep, SynchronizableEntity updatedEntity) { try { Field reverseField = dep.targetType.getDeclaredField(dep.reverseFieldName); reverseField.setAccessible(true); if (dep.refType == RefType.SINGLE) { // 单引用反向设置 reverseField.set(updatedEntity, this); } else if (dep.refType == RefType.LIST) { // 列表引用反向添加 @SuppressWarnings("unchecked") List<SynchronizableEntity> list = (List<SynchronizableEntity>) reverseField.get(updatedEntity); if (list == null) { list = new ArrayList<>(); reverseField.set(updatedEntity, list); } if (!list.contains(this)) { list.add(this); } } } catch (Exception e) { Log.e("Sync", "更新反向字段失败", e); } } // 实际同步逻辑 private void syncInternal(SyncCallback callback) { switch (state) { case NEW: createToServer(callback); break; case MODIFIED: updateToServer(callback); break; case DELETED: deleteFromServer(callback); break; default: if (callback != null) callback.onSyncSuccess(this); } } // 依赖关系描述类 private static class Dependency { SynchronizableEntity entity; Class<?> targetType; RefType refType; boolean isBidirectional; String reverseFieldName; Dependency(SynchronizableEntity entity, Class<?> targetType, RefType refType, boolean isBidirectional, String reverseFieldName) { this.entity = entity; this.targetType = targetType; this.refType = refType; this.isBidirectional = isBidirectional; this.reverseFieldName = reverseFieldName; } } /** 获取所有依赖实体 根据 @RefTo 注解解析: target: 目标实体类型 type: 引用类型(SINGLE/LIST) bidirectional: 是否双向关联 reverseField: 反向字段名 */ private List getDependencies() { List dependencies = new ArrayList<>(); for (Field field : this.getClass().getDeclaredFields()) { try { field.setAccessible(true); RefTo refAnnotation = field.getAnnotation(RefTo.class); if (refAnnotation == null) continue; Object value = field.get(this); Class<?> targetType = refAnnotation.target(); RefType refType = refAnnotation.type(); boolean bidirectional = refAnnotation.bidirectional(); String reverseField = refAnnotation.reverseField(); if (refType == RefType.SINGLE && value instanceof SynchronizableEntity) { SynchronizableEntity entity = (SynchronizableEntity) value; if (entity.requiresSync()) { dependencies.add(new Dependency(entity, targetType, refType, bidirectional, reverseField)); } } else if (refType == RefType.LIST && value instanceof List) { for (Object item : (List<?>) value) { if (item instanceof SynchronizableEntity) { SynchronizableEntity entity = (SynchronizableEntity) item; if (entity.requiresSync()) { dependencies.add(new Dependency(entity, targetType, refType, bidirectional, reverseField)); } } } } } catch (Exception e) { Log.e(“Sync”, “获取依赖失败”, e); } } // 确保单引用实体优先同步 dependencies.sort((d1, d2) -> { if (d1.refType == RefType.SINGLE && d2.refType != RefType.SINGLE) return -1; if (d1.refType != RefType.SINGLE && d2.refType == RefType.SINGLE) return 1; return 0; }); return dependencies; } // 错误处理(带重试机制) private void handleSyncError(String error, SyncCallback callback) { if (retryCount < MAX_RETRY) { retryCount++; new Handler(Looper.getMainLooper()).postDelayed(() -> syncWithDependencies(callback), 3000); } else { state = SyncState.MODIFIED; retryCount = 0; if (callback != null) callback.onSyncFailure(error); } } // 检查是否需要同步 boolean requiresSync() { return state == SyncState.NEW || state == SyncState.MODIFIED || state == SyncState.DELETED; } // 同步回调接口 public interface SyncCallback { void onSyncSuccess(SynchronizableEntity entity); void onSyncFailure(String error); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; return Objects.equals(getId(), ((SynchronizableEntity) o).getId()); } } E FATAL EXCEPTION: OkHttp Dispatcher Process: com.example.kucun2, PID: 9074 java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.example.kucun2.entity.data.SynchronizableEntity at com.example.kucun2.entity.data.SynchronizableEntity$ 1.onSuccess(SynchronizableEntity.java:137) at com.example.kucun2.entity.data.ApiClient$ 1.onResponse(ApiClient.java:62) at okhttp3.RealCall$ AsyncCall.execute(RealCall.java:174) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$ Worker.run(ThreadPoolExecutor.java:644) at java.lang.Thread.run(Thread.java:1042) 2025-06-18 23:20:52.449 9074-12671 Process com.example.kucun2 I Sending signal. PID: 9074 SIG: 9 Type responseType = new TypeToken<Information<T>>() {}.getType();不管用?为毛会要解析为SynchronizableEntity
最新发布
06-19
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.RefTo; import com.example.kucun2.entity.RefType; import com.example.kucun2.function.MyAppFunction; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** * 可同步实体基类 * 实现实体状态管理、属性变更监听、服务端同步等功能 */ public abstract class SynchronizableEntity implements EntityClassGrassrootsid { private static String TAG="SynchronizableEntity"; // 实体同步状态枚举 public enum SyncState { NEW, MODIFIED, DELETED, SYNCING, SYNCED, PRESERVED } private SyncState state = SyncState.NEW; private static final int MAX_RETRY = 3; private int retryCount = 0; private static final Map<String, Boolean> syncLocks = new ConcurrentHashMap<>(); private static final ThreadLocal<Set<String>> syncStack = ThreadLocal.withInitial(HashSet::new); // 属性变更支持 private transient PropertyChangeSupport changeSupport; // 属性缓存 private final Map<String, Object> propertyCache = new HashMap<>(); private static boolean syncEnabled = true; // 全局同步开关 //================ 基础方法 ================// /** 判断是否为预保存对象 */ public boolean isPreservedObject() { return this.getId() != null && this.getId() == -1; } /** 设置全局同步开关 */ public static void setSyncEnabled(boolean enabled) { syncEnabled = enabled; } /** 获取/设置实体状态 */ public SyncState getState() { return this.state; } public void setState(SyncState state) { this.state = state; } //================ 属性变更监听 ================// /** 添加属性变更监听器 */ 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); } } // 触发属性变更时自动同步 protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (changeSupport != null && changeSupport.hasListeners(propertyName)) { propertyCache.put(propertyName, newValue); changeSupport.firePropertyChange(propertyName, oldValue, newValue); } // 状态为SYNCED时标记为需要同步 if (state == SyncState.SYNCED) { state = SyncState.MODIFIED; } // 启动同步(非新建实体) if (state != SyncState.NEW && state != SyncState.SYNCING) { scheduleSync(); } } //================ 端点URL生成 ================// /** 获取操作端点URL */ public String getEndpoint(String type) { String key = "url_" + type + "_" + this.getClass().getSimpleName().toLowerCase(); return MyAppFunction.getStringResource("string", key); } //================ 核心同步方法 ================// /** 执行同步操作 */ public void sync(SyncCallback callback) { if (!syncEnabled) return; // 检查全局开关 try { switch (this.state) { case NEW: createToServer(callback); break; case MODIFIED: updateToServer(callback); break; case DELETED: deleteFromServer(callback); break; } } catch (Exception e) { Log.e("SyncError", "Sync failed for " + getClass().getSimpleName(), e); } } //================ 服务端操作 ================// /** 创建实体到服务端 */ private void createToServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource("string", "url") + getEndpoint("add"); Information<SynchronizableEntity> request = new Information<>(200, "Create", this); Log.d(TAG, "createToServer: "+endpoint); ApiClient.post(endpoint, request, new ApiClient.ApiCallback<SynchronizableEntity>() { @Override public void onSuccess(Information<SynchronizableEntity> response) { if (response.getData() != null) { setId(response.getData().getId()); // 设置服务器ID } state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } /** 更新实体到服务端 */ private void updateToServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource("string", "url") + getEndpoint("update") + "/" + getId(); Information<SynchronizableEntity> request = new Information<>(200, "Update", this); ApiClient.put(endpoint, request, new ApiClient.ApiCallback<SynchronizableEntity>() { @Override public void onSuccess(Information<SynchronizableEntity> response) { state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } /** 从服务端删除实体 */ private void deleteFromServer(SyncCallback callback) { String endpoint = MyAppFunction.getStringResource("string", "url") + getEndpoint("delete") + "/" + getId(); ApiClient.delete(endpoint, new ApiClient.ApiCallback<Void>() { @Override public void onSuccess(Information<Void> response) { state = SyncState.SYNCED; if (callback != null) callback.onSyncSuccess(SynchronizableEntity.this); } @Override public void onError(int statusCode, String error) { handleSyncError(error, callback); } }); } // 安排同步任务(防止频繁同步) private void scheduleSync() { String lockKey = this.getClass().getName() + getId(); synchronized (syncLocks) { if (syncLocks.containsKey(lockKey)) return; syncLocks.put(lockKey, true); } new Handler(Looper.getMainLooper()).postDelayed(() -> { syncWithDependencies(null); synchronized (syncLocks) { syncLocks.remove(lockKey); } }, 1000); // 1秒延迟 } /** * 带依赖关系的同步方法 * * 根据 @RefTo 注解的依赖关系,确保: * 1. 双向关联的反向字段会同步更新 * 2. 列表关联的所有元素会按顺序同步 * 3. 单引用实体优先同步 * * @param callback 同步完成回调 */ public void syncWithDependencies(SyncCallback callback) { // 检测循环依赖 String entityKey = this.getClass().getName() + getId(); Set<String> currentStack = syncStack.get(); if (currentStack.contains(entityKey)) { Log.w("Sync", "检测到循环依赖: " + entityKey); if (callback != null) callback.onSyncFailure("循环依赖"); return; } currentStack.add(entityKey); state = SyncState.SYNCING; try { // 获取所有依赖实体 List<Dependency> dependencies = getDependencies(); if (dependencies.isEmpty()) { syncInternal(callback); return; } // 同步所有依赖实体 AtomicInteger counter = new AtomicInteger(dependencies.size()); for (Dependency dep : dependencies) { dep.entity.syncWithDependencies(new SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { // 处理双向关联的反向字段 if (dep.isBidirectional) { updateReverseField(dep, entity); } if (counter.decrementAndGet() == 0) { syncInternal(callback); } } @Override public void onSyncFailure(String error) { if (callback != null) { callback.onSyncFailure(error); } state = SyncState.MODIFIED; // 重置状态 } }); } } finally { currentStack.remove(entityKey); } } // 更新双向关联的反向字段 private void updateReverseField(Dependency dep, SynchronizableEntity updatedEntity) { try { Field reverseField = dep.targetType.getDeclaredField(dep.reverseFieldName); reverseField.setAccessible(true); if (dep.refType == RefType.SINGLE) { // 单引用反向设置 reverseField.set(updatedEntity, this); } else if (dep.refType == RefType.LIST) { // 列表引用反向添加 @SuppressWarnings("unchecked") List<SynchronizableEntity> list = (List<SynchronizableEntity>) reverseField.get(updatedEntity); if (list == null) { list = new ArrayList<>(); reverseField.set(updatedEntity, list); } if (!list.contains(this)) { list.add(this); } } } catch (Exception e) { Log.e("Sync", "更新反向字段失败", e); } } // 实际同步逻辑 private void syncInternal(SyncCallback callback) { switch (state) { case NEW: createToServer(callback); break; case MODIFIED: updateToServer(callback); break; case DELETED: deleteFromServer(callback); break; default: if (callback != null) callback.onSyncSuccess(this); } } // 依赖关系描述类 private static class Dependency { SynchronizableEntity entity; Class<?> targetType; RefType refType; boolean isBidirectional; String reverseFieldName; Dependency(SynchronizableEntity entity, Class<?> targetType, RefType refType, boolean isBidirectional, String reverseFieldName) { this.entity = entity; this.targetType = targetType; this.refType = refType; this.isBidirectional = isBidirectional; this.reverseFieldName = reverseFieldName; } } /** * 获取所有依赖实体 * * 根据 @RefTo 注解解析: * - target: 目标实体类型 * - type: 引用类型(SINGLE/LIST) * - bidirectional: 是否双向关联 * - reverseField: 反向字段名 */ private List<Dependency> getDependencies() { List<Dependency> dependencies = new ArrayList<>(); for (Field field : this.getClass().getDeclaredFields()) { try { field.setAccessible(true); RefTo refAnnotation = field.getAnnotation(RefTo.class); if (refAnnotation == null) continue; Object value = field.get(this); Class<?> targetType = refAnnotation.target(); RefType refType = refAnnotation.type(); boolean bidirectional = refAnnotation.bidirectional(); String reverseField = refAnnotation.reverseField(); if (refType == RefType.SINGLE && value instanceof SynchronizableEntity) { SynchronizableEntity entity = (SynchronizableEntity) value; if (entity.requiresSync()) { dependencies.add(new Dependency(entity, targetType, refType, bidirectional, reverseField)); } } else if (refType == RefType.LIST && value instanceof List) { for (Object item : (List<?>) value) { if (item instanceof SynchronizableEntity) { SynchronizableEntity entity = (SynchronizableEntity) item; if (entity.requiresSync()) { dependencies.add(new Dependency(entity, targetType, refType, bidirectional, reverseField)); } } } } } catch (Exception e) { Log.e("Sync", "获取依赖失败", e); } } // 确保单引用实体优先同步 dependencies.sort((d1, d2) -> { if (d1.refType == RefType.SINGLE && d2.refType != RefType.SINGLE) return -1; if (d1.refType != RefType.SINGLE && d2.refType == RefType.SINGLE) return 1; return 0; }); return dependencies; } // 错误处理(带重试机制) private void handleSyncError(String error, SyncCallback callback) { if (retryCount < MAX_RETRY) { retryCount++; new Handler(Looper.getMainLooper()).postDelayed(() -> syncWithDependencies(callback), 3000); } else { state = SyncState.MODIFIED; retryCount = 0; if (callback != null) callback.onSyncFailure(error); } } // 检查是否需要同步 boolean requiresSync() { return state == SyncState.NEW || state == SyncState.MODIFIED || state == SyncState.DELETED; } // 同步回调接口 public interface SyncCallback { void onSyncSuccess(SynchronizableEntity entity); void onSyncFailure(String error); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; return Objects.equals(getId(), ((SynchronizableEntity) o).getId()); } } package com.example.kucun2.entity.data; import android.os.Handler; import android.os.Looper; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; public class SynchronizedList<T extends SynchronizableEntity> implements List<T> { private final List<T> list = new ArrayList<>(); private final Class<T> entityType; private final EntityChangeListener<T> entityChangeListener = new EntityChangeListener<>(); public SynchronizedList(Class<T> entityType) { this.entityType = entityType; } //================ 监听器管理 ================// private static class EntityChangeListener<T extends SynchronizableEntity> implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { ((T) evt.getSource()).sync(null); } } private void registerListener(T element) { if (element != null) { element.addPropertyChangeListener(entityChangeListener); } } private void unregisterListener(Object element) { if (element instanceof SynchronizableEntity) { ((SynchronizableEntity) element).removePropertyChangeListener(entityChangeListener); } } //================ 核心集合操作 ================// @Override public boolean add(T element) { if (element != null && !list.contains(element)) { registerListener(element); boolean added = list.add(element); // 新增:自动触发新建实体同步 if (added && element.getState() == SynchronizableEntity.SyncState.NEW) { triggerAutoSync(element); } return added; } return false; } // 处理自动同步逻辑 private void triggerAutoSync(T element) { // 确保在主线程执行 new Handler(Looper.getMainLooper()).post(() -> { // 检查实体是否仍在集合中 if (list.contains(element)) { // 使用带依赖关系的同步 element.syncWithDependencies(new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { Log.i("AutoSync", "实体同步成功: " + entity.getClass().getSimpleName()); } @Override public void onSyncFailure(String error) { Log.e("AutoSync", "同步失败: " + error); // 失败处理:重试或通知用户 } }); } }); } @Override public boolean remove(Object o) { if (list.remove(o)) { unregisterListener(o); return true; } return false; } @Override public void clear() { for (T element : list) { unregisterListener(element); } list.clear(); } //================ 批量操作 ================// @Override public boolean addAll(@NonNull Collection<? extends T> c) { boolean modified = false; for (T element : c) { if (add(element)) { modified = true; } } return modified; } @Override public boolean addAll(int index, @NonNull Collection<? extends T> c) { if (index < 0 || index > size()) throw new IndexOutOfBoundsException(); int i = index; for (T element : c) { if (element != null && !list.contains(element)) { add(i++, element); } } return i > index; } @Override public boolean removeAll(@NonNull Collection<?> c) { boolean modified = false; for (Object o : c) { while (remove(o)) { modified = true; } } return modified; } @Override public boolean retainAll(@NonNull Collection<?> c) { boolean modified = false; Iterator<T> it = iterator(); while (it.hasNext()) { T element = it.next(); if (!c.contains(element)) { it.remove(); modified = true; } } return modified; } //================ 索引操作 ================// @Override public T get(int index) { return list.get(index); } @Override public T set(int index, T element) { if (element == null) throw new NullPointerException(); if (list.contains(element)) throw new IllegalArgumentException("Duplicate element"); T old = list.get(index); unregisterListener(old); registerListener(element); return list.set(index, element); } @Override public void add(int index, T element) { if (element == null) throw new NullPointerException(); if (list.contains(element)) throw new IllegalArgumentException("Duplicate element"); registerListener(element); list.add(index, element); } @Override public T remove(int index) { T removed = list.remove(index); if (removed != null) { unregisterListener(removed); } return removed; } //================ 查询操作 ================// @Override public int size() { return list.size(); } @Override public boolean isEmpty() { return list.isEmpty(); } @Override public boolean contains(Object o) { return list.contains(o); } @Override public boolean containsAll(@NonNull Collection<?> c) { return list.containsAll(c); } @Override public int indexOf(@Nullable Object o) { return list.indexOf(o); } @Override public int lastIndexOf(@Nullable Object o) { return list.lastIndexOf(o); } //================ 迭代器实现 ================// @NonNull @Override public Iterator<T> iterator() { return new Iterator<>() { private final Iterator<T> iterator = list.iterator(); private T current; @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { current = iterator.next(); return current; } @Override public void remove() { unregisterListener(current); iterator.remove(); } }; } @NonNull @Override public ListIterator<T> listIterator() { return listIterator(0); } @NonNull @Override public ListIterator<T> listIterator(int index) { return new ListIterator<T>() { private final ListIterator<T> iterator = list.listIterator(index); private T lastReturned; @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { lastReturned = iterator.next(); return lastReturned; } @Override public boolean hasPrevious() { return iterator.hasPrevious(); } @Override public T previous() { lastReturned = iterator.previous(); return lastReturned; } @Override public int nextIndex() { return iterator.nextIndex(); } @Override public int previousIndex() { return iterator.previousIndex(); } @Override public void remove() { unregisterListener(lastReturned); iterator.remove(); lastReturned = null; } @Override public void set(T t) { if (t == null) throw new NullPointerException(); if (list.contains(t)) throw new IllegalArgumentException("Duplicate element"); unregisterListener(lastReturned); registerListener(t); iterator.set(t); lastReturned = t; } @Override public void add(T t) { if (t == null) throw new NullPointerException(); if (list.contains(t)) throw new IllegalArgumentException("Duplicate element"); registerListener(t); iterator.add(t); lastReturned = null; } }; } //================ 数组转换 ================// @NonNull @Override public Object[] toArray() { return list.toArray(); } @NonNull @Override public <T1> T1[] toArray(@NonNull T1[] a) { return list.toArray(a); } //================ 子视图 ================// @NonNull @Override public List<T> subList(int fromIndex, int toIndex) { throw new UnsupportedOperationException("subList not supported"); } } 添加数据后根本没有不,日志都没
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值