feat(O): Android 首页近期动态实时刷新

- 新增 ActivityEventBus(进程级静态回调, 主线程派发)
- PlatformServiceManager/DeviceControlActivity/TuyaSdkService 在动态落库成功后 notify
- HomeFragment 注册监听并 400ms 防抖重载近期动态, onResume/onHiddenChanged 兜底刷新
This commit is contained in:
2995840376 2026-10-28 10:48:10 +08:00
parent 4c8aa5459d
commit da28d3b543
5 changed files with 111 additions and 0 deletions

View File

@ -145,6 +145,8 @@ public class PlatformServiceManager {
@Override
public void onResponse(retrofit2.Call<Result<Void>> call,
retrofit2.Response<Result<Void>> response) {
// 动态已落库,通知首页「近期动态」实时刷新
com.xhai.iot.util.ActivityEventBus.notifyChanged(device.getDeviceId());
}
@Override

View File

@ -95,6 +95,8 @@ public class TuyaSdkService {
@Override
public void onResponse(retrofit2.Call<com.xhai.iot.model.Result<Integer>> call,
retrofit2.Response<com.xhai.iot.model.Result<Integer>> response) {
// 后端已记录 DP 变化动态(source=panel),通知首页刷新近期动态
com.xhai.iot.util.ActivityEventBus.notifyChanged(devId);
}
@Override

View File

@ -1122,6 +1122,8 @@ public class DeviceControlActivity extends AppCompatActivity {
@Override
public void onResponse(retrofit2.Call<com.xhai.iot.model.Result<Void>> call,
retrofit2.Response<com.xhai.iot.model.Result<Void>> response) {
// 动态已落库,通知首页「近期动态」实时刷新
com.xhai.iot.util.ActivityEventBus.notifyChanged(deviceId);
}
@Override

View File

@ -28,6 +28,7 @@ import com.xhai.iot.model.Result;
import com.xhai.iot.model.TuyaDevice;
import com.xhai.iot.service.TuyaSdkService;
import com.xhai.iot.ui.adapter.HomeDeviceAdapter;
import com.xhai.iot.util.ActivityEventBus;
import com.xhai.iot.util.SessionManager;
import com.xhai.iot.util.ThemeManager;
import com.thingclips.smart.sdk.api.IDevListener;
@ -93,6 +94,8 @@ public class HomeFragment extends Fragment {
loadRecentActivities();
// 注册设备状态回调,物理开关/远程状态变化时实时刷新列表
TuyaSdkService.registerStatusCallback(deviceStatusCallback);
// 注册动态事件回调:任意控制落库成功后,首页「近期动态」立即刷新
ActivityEventBus.register(activityEventListener);
}
@Override
@ -100,6 +103,11 @@ public class HomeFragment extends Fragment {
super.onDestroyView();
unregisterAllTuyaListeners();
TuyaSdkService.unregisterStatusCallback(deviceStatusCallback);
ActivityEventBus.unregister(activityEventListener);
if (activityRefreshTask != null) {
activityRefreshHandler.removeCallbacks(activityRefreshTask);
activityRefreshTask = null;
}
}
@Override
@ -112,6 +120,8 @@ public class HomeFragment extends Fragment {
adapter.notifyDataSetChanged();
}
loadDevicesFromBackend();
// 兜底:页面回到前台时同步一次近期动态(覆盖进程内事件丢失的情况)
scheduleActivityRefresh();
}
}
@ -122,9 +132,35 @@ public class HomeFragment extends Fragment {
if (!hidden && adapter != null && isAdded()) {
adapter.setAccentColor(ThemeManager.getInstance(requireContext()).accent().value);
adapter.notifyDataSetChanged();
// 兜底:切回首页时同步一次近期动态
scheduleActivityRefresh();
}
}
// ==================== 近期动态实时刷新 ====================
/** 动态事件回调:控制落库成功后触发「近期动态」重载 */
private final ActivityEventBus.Listener activityEventListener = deviceId -> {
if (!isAdded()) return;
android.util.Log.i("HomeFragment", "动态事件触发刷新: deviceId=" + deviceId);
scheduleActivityRefresh();
};
/** 动态刷新防抖时间(合并短时间内连续触发) */
private static final long ACTIVITY_REFRESH_DEBOUNCE_MS = 400L;
private final android.os.Handler activityRefreshHandler =
new android.os.Handler(android.os.Looper.getMainLooper());
private Runnable activityRefreshTask;
/** 防抖刷新近期动态 */
private void scheduleActivityRefresh() {
if (activityRefreshTask != null) {
activityRefreshHandler.removeCallbacks(activityRefreshTask);
}
activityRefreshTask = this::loadRecentActivities;
activityRefreshHandler.postDelayed(activityRefreshTask, ACTIVITY_REFRESH_DEBOUNCE_MS);
}
// ==================== 刷新节流(避免高频全量重绑导致界面闪动) ====================
/**

View File

@ -0,0 +1,69 @@
package com.xhai.iot.util;
import android.os.Handler;
import android.os.Looper;
import java.util.ArrayList;
import java.util.List;
/**
* 设备动态(操控记录)事件总线。
*
* <p>首页「近期动态」是后端 device_activity_log 的快照,控制动作本身走涂鸦 SDK 直连、
* 不经后端,所以必须由客户端在动态<b>落库成功</b>之后主动通知 UI 刷新,否则首页列表
* 一直停留在进入页面那一刻的静态数据。</p>
*
* <p>实现方式与 {@code TuyaSdkService} 的状态回调保持一致:进程级静态回调列表,
* 页面注册/注销,事件在主线程派发。</p>
*/
public final class ActivityEventBus {
/** 动态变更监听 */
public interface Listener {
/**
* @param deviceId 发生动态的设备ID,可能为 null(表示全局刷新)
*/
void onActivityChanged(String deviceId);
}
private static final List<Listener> listeners = new ArrayList<>();
private static final Handler MAIN = new Handler(Looper.getMainLooper());
private ActivityEventBus() {
}
/** 注册监听 */
public static void register(Listener listener) {
if (listener == null) return;
synchronized (listeners) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
}
/** 注销监听 */
public static void unregister(Listener listener) {
if (listener == null) return;
synchronized (listeners) {
listeners.remove(listener);
}
}
/** 通知所有监听:设备动态已新增(落库成功后才调用) */
public static void notifyChanged(String deviceId) {
final List<Listener> snapshot;
synchronized (listeners) {
if (listeners.isEmpty()) return;
snapshot = new ArrayList<>(listeners);
}
MAIN.post(() -> {
for (Listener l : snapshot) {
try {
l.onActivityChanged(deviceId);
} catch (Exception ignored) {
}
}
});
}
}