全局Listeners持有者

Java监听器模式实践
本文介绍了一种基于Java实现的监听器模式,通过定义接口和抽象类来简化事件处理过程。该模式支持不同类型的监听器,并利用泛型和反射机制实现了灵活的事件分发。
package com.test;

public interface IBaseListener {
}


package com.test;

public interface OnXListener extends IBaseListener {
	public void onXyes();

	public void onXno();

	public static class AbsOnXListener implements OnXListener {
		@Override
		public void onXyes() {
		}

		@Override
		public void onXno() {
		}
	}
}


package com.test;

public interface OnYListener extends IBaseListener {
	public void onYyes(String s);

	public void onYno(String s);

	public static abstract class AbsOnYListener implements OnYListener {
		@Override
		public void onYyes(String s) {
		}

		@Override
		public void onYno(String s) {
		}
	}
}


package com.test;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class ListenerHolder {
	private static Set<OnXListener> sXListeners = new CopyOnWriteArraySet<OnXListener>();
	private static Set<OnYListener> sYListeners = new CopyOnWriteArraySet<OnYListener>();

	@SuppressWarnings({ "unchecked" })
	public static <T extends IBaseListener> void callListeners(Class<T> clz, IListenerExecutor<T> executor) {
		if (OnXListener.class.isAssignableFrom(clz)) {
			for (OnXListener listener : sXListeners) {
				executor.execute((T) listener);
			}
		} else if (OnYListener.class.isAssignableFrom(clz)) {
			for (OnYListener listener : sYListeners) {
				executor.execute((T) listener);
			}
		}
	}

	public static void addListener(IBaseListener listener) {
		if (listener instanceof OnXListener) {
			sXListeners.add((OnXListener) listener);
		}
		if (listener instanceof OnYListener) {
			sYListeners.add((OnYListener) listener);
		}
	}

	public static void removeListener(IBaseListener listener) {
		if (listener instanceof OnXListener) {
			sXListeners.remove(listener);
		}
		if (listener instanceof OnYListener) {
			sYListeners.remove(listener);
		}
	}

	public static void clear() {
		sXListeners.clear();
		sYListeners.clear();
	}

	public static interface IListenerExecutor<T extends IBaseListener> {
		public void execute(T listener);
	}

}


package com.test;

import com.test.ListenerHolder.IListenerExecutor;

public class Test {
	public static void main(String[] args) {
		// 触发监听器
		final String s = "abc";
		ListenerHolder.callListeners(OnYListener.class, new IListenerExecutor<OnYListener>() {
			@Override
			public void execute(OnYListener listener) {
				listener.onYyes(s);
			}
		});
	}
	
	// 添加监听器
	public void addListener(IBaseListener listener) {
		ListenerHolder.addListener(listener);
	}
	
	// 移除监听器
	public void removeListener(IBaseListener listener) {
		ListenerHolder.removeListener(listener);
	}
	
}


package com.kotei.fusionpositionengine; import android.icu.text.SimpleDateFormat; import android.location.Location; import androidx.annotation.NonNull; import java.util.Date; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 多源传感器融合定位引擎核心类 * 功能:集成GNSS/IMU/Vehicle等传感器数据,通过JNI调用本地算法输出高精度定位 * 设计模式:单例模式 + 观察者模式 */ public class FusionPosition { private static final String TAG = FusionPosition.class.getName(); // JNI接口实例(native方法声明在FusionPositionJNI类中) private final FusionPositionJNI jni; // 定时任务调度器(用于周期性地通知监听器) private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); // 线程安全的监听器列表(采用写时复制避免并发问题) private CopyOnWriteArrayList<FusionPositionListener> listeners = new CopyOnWriteArrayList<>(); // 位置更新频率(Hz) private int updateFrequencyHz = 1; //时间戳格式 private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); /** * 私有构造器(单例模式) */ private FusionPosition() { log("初始化融合定位引擎"); this.jni = new FusionPositionJNI(); this.scheduler = Executors.newSingleThreadScheduledExecutor(); this.listeners = new CopyOnWriteArrayList<>(); startPolling(); } /** * 构造实例持有者 */ private static final class MInstanceHolder { static final FusionPosition mInstance = new FusionPosition(); } /** * 获取全局唯一实例 * @return FusionPosition单例实例 */ public static FusionPosition getInstance() { return MInstanceHolder.mInstance; } /** * 位置更新监听器接口 */ // public interface FusionPositionListener { // /** // * 当位置更新时回调 // * @param jsonLocation JSON格式的定位信息 // */ // void onFusionPositionUpdate(String jsonLocation); // } public interface FusionPositionListener { void onFusionPositionUpdate(LocationMsg locationMsg); } /** * 注册位置监听器 * @param listener 实现LocationListener接口的对象 */ public void addLocationListener(FusionPositionListener listener) { if (listener != null) { listeners.addIfAbsent(listener); } } /** * 移除位置监听器 * @param listener 需要移除的监听器对象 */ public void removeLocationListener(FusionPositionListener listener) { listeners.remove(listener); } /** * 设置位置更新频率 * @param hz 频率值(1-50Hz) */ public void setUpdateFrequency(int hz) { this.updateFrequencyHz = Math.min(50, Math.max(1, hz)); restartPolling(); } // 启动周期性位置通知 private void startPolling() { scheduler.scheduleAtFixedRate(this::notifyListeners, 0, 1000 / updateFrequencyHz, TimeUnit.MILLISECONDS); } // 重新启动轮询(频率变化时调用) private void restartPolling() { scheduler.shutdownNow(); startPolling(); } // 通知所有监听器 // private void notifyListeners() { // String location = getLocationMsg(); //// Location temp = new Location(location); // for (FusionPositionListener listener : listeners) { // try { //// listener.onFusionPositionUpdate(temp); // listener.onFusionPositionUpdate(location); // } catch (Exception e) { // System.err.println("监听器回调异常: " + e.getMessage()); // } // } // } private void notifyListeners() { String jsonLocation = getLocationMsg(); // 从 JNI 获取 JSON 字符串 LocationMsg locationMsg = LocationMsg.fromJson(jsonLocation); // 解析为对象 for (FusionPositionListener listener : listeners) { try { listener.onFusionPositionUpdate(locationMsg); // 传入 LocationMsg } catch (Exception e) { logError("监听器回调异常", e); } } } /** * 设置GNSS定位数据 * @param gnssMsg 非空的GNSS定位数据对象 * @throws NullPointerException 当参数为null时抛出 */ public void setGNSSMsg(@NonNull GNSSMsg gnssMsg) { try { // 通过JNI接口将数据传递给本地层处理 jni.setGNSSMsg(gnssMsg); } catch (Exception e) { // 将原生异常转换为Java异常 throw new NativeException("Failed to set GNSSMsg message", e); } } /** * 设置车辆运动数据(IMU+Vehicle) * @param imu 非空的IMU传感器数据对象 * @param vehicle 非空的车辆状态数据对象 * @param dt 时间间隔(秒) * @throws NullPointerException 当任意参数为null时抛出 */ public void setCarMsg(@NonNull IMUMsg imu, @NonNull VehicleMsg vehicle, double dt) { try { // 组合传递IMU和车辆数据到本地层 jni.setCarMsg(imu, vehicle, dt); } catch (Exception e) { // 将原生异常转换为Java异常 throw new NativeException("Failed to set CarMsg message", e); } } /** * 设置卫星定位数据 * @param satellite 非空的卫星数据对象 * @throws NullPointerException 当参数为null时抛出 */ public void setSatelliteMsg(@NonNull SatelliteMsg satellite) { try { // 通过JNI接口传递卫星数据 jni.setSatelliteMsg(satellite); } catch (Exception e) { // 将原生异常转换为Java异常 throw new NativeException("Failed to set SatelliteMsg message", e); } } /** * 获取格式化后的定位信息 * @return JSON格式的定位信息字符串 * @throws NativeException 当JNI调用发生错误时抛出 */ public String getLocationMsg() { String locationMsg = ""; try { // 调用本地方法获取定位信息 locationMsg = jni.getLocationMsg(); } catch (Exception e) { // 将原生异常转换为Java异常 throw new NativeException("Failed to get location message", e); } return locationMsg; } private void log(String message) { System.out.println(dateFormat.format(new Date()) + " [" + TAG + "] " + message); } private void logError(String message, Exception e) { System.err.println(dateFormat.format(new Date()) + " [" + TAG + "] ERROR: " + message + " - " + e.getClass().getSimpleName() + ": " + e.getMessage()); } } 总结出所有与json相关的代码,并且列举出差异,使用locationmsg前后
最新发布
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzyjr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值