You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API 26(Oreo)中onResume获取单例存储值空指针问题

解决Android Oreo中单例类存取值的空指针问题

听起来你遇到的问题大概率和Fragment生命周期的执行顺序有关,而且这个顺序在Android Oreo上的严格表现刚好踩中了你的代码逻辑漏洞。我来帮你拆解清楚:

问题根源:Fragment切换时的生命周期顺序

当你从第一个商品列表Fragment切换到第二个Fragment时,系统的生命周期调用顺序是固定的:

  1. 第一个Fragment执行onPause()
  2. 第二个Fragment执行onResume()
  3. 第一个Fragment执行onStop()

你现在把选中商品的存储逻辑放在第一个Fragment的onStop()方法里,但这时候第二个Fragment的onResume()已经先执行完了——也就是说,当你在第二个Fragment里尝试从单例取值时,数据还没被存进去,自然就抛出空指针异常了。

为什么只在Oreo出现?可能是更早的Android版本中,你没遇到这个问题(比如某些场景下生命周期调度有差异,或者测试覆盖不到),但Oreo对Fragment生命周期的执行顺序管控更严格,这个固定顺序被明确执行了。

解决方案

1. 最稳妥:在用户操作完成时立即存值

不要等到Fragment生命周期回调才存数据,应该在用户选中商品的那一刻就把值存入单例。比如在列表项的点击事件里直接处理:

// 第一个Fragment中商品列表的点击事件
itemView.setOnClickListener(v -> {
    // 选中商品后立即存入单例
    ProductSingleton.getInstance().setSelectedProduct(currentItem);
    // 再执行Fragment切换逻辑
    switchToSecondFragment();
});

这样不管生命周期怎么调度,切换到第二个Fragment时数据已经准备好了,从根源上避免了时序问题。

2. 调整存值的生命周期时机

如果实在没办法在点击时存,也可以把存值逻辑移到第一个Fragment的onPause()方法里——因为onPause()的执行是在第二个Fragment的onResume()之前,能保证数据在第二个Fragment取值前已经被存入。

3. 验证单例实现的正确性

确保你的单例类是线程安全且不会被意外回收的,比如采用双重校验锁的标准实现:

public class ProductSingleton {
    private static volatile ProductSingleton instance;
    private Product selectedProduct;

    private ProductSingleton() {}

    public static ProductSingleton getInstance() {
        if (instance == null) {
            synchronized (ProductSingleton.class) {
                if (instance == null) {
                    instance = new ProductSingleton();
                }
            }
        }
        return instance;
    }

    public Product getSelectedProduct() {
        return selectedProduct;
    }

    public void setSelectedProduct(Product selectedProduct) {
        this.selectedProduct = selectedProduct;
    }
}

如果单例本身实现有漏洞(比如非线程安全导致实例重复创建),也可能出现取值为空的情况,但结合你只在Oreo出现问题的描述,这个可能性相对较小。

内容的提问来源于stack exchange,提问作者user3792429

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:27:17