Blankj / Blankj/AndroidUtilCode

NumberUtils formatting fails to update on system language change due to static ThreadLocal caching

Đang mở
#1,848 0 bình luận 0 reaction 1 người được giao Được @Blankj nhận Xem trên GitHub
bug
Ngôn ngữ chính
Java
Star
33.6k
Fork
10.6k
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

## 描述 Bug
NumberUtils 类使用静态 ThreadLocal (DF_THREAD_LOCAL) 缓存格式化对象。initialValue() 方法仅在线程首次调用时执行,捕获当时的 Locale.getDefault()。

如果用户在 App 运行过程中切换系统语言(例如从英语切换到德语),由于线程池中的线程已初始化,ThreadLocal 中的 DecimalFormat 不会重建,依然持有旧的 Locale 配置。这将导致数字格式化(如小数点符号 . vs ,)不一致,部分界面显示旧语言格式,部分显示新语言格式。

- AndroidUtilCode 的版本: 1.29.0
- - 出现 Bug 的设备型号: All (通用逻辑问题)
- - - 设备的 Android 版本: All

## 相关代码
// NumberUtils.java
private static final ThreadLocal DF_THREAD_LOCAL = new ThreadLocal() {
@Override
protected DecimalFormat initialValue() {
// 这里的 NumberFormat.getInstance() 使用了当时的 Locale.getDefault()
// 一旦缓存,后续 Locale 变更不会反映在这里
return (DecimalFormat) NumberFormat.getInstance();
}
};

public static DecimalFormat getSafeDecimalFormat() {
return DF_THREAD_LOCAL.get();
}

## 预期行为 (Expected Behavior) 当系统语言发生变化时,NumberUtils.format() 应当使用新的 Locale 进行格式化。

## 修复建议 (Suggested Fix) 建议在获取缓存时校验 Locale,或者直接移除 ThreadLocal(在 ART 虚拟机上 DecimalFormat 创建开销通常可接受)。
public static DecimalFormat getSafeDecimalFormat() {
DecimalFormat df = DF_THREAD_LOCAL.get();
// 检查当前 Locale 是否发生变化
if (!df.getDecimalFormatSymbols().getLocale().equals(Locale.getDefault())) {
df = (DecimalFormat) NumberFormat.getInstance();
DF_THREAD_LOCAL.set(df);
}
return df;
}

## 堆栈信息 (Stack Trace) 无崩溃 (No Crash),属于逻辑错误 (Logic Error)。

## 截图 N/A

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.