Android 的 Application 类中持有静态 SP 为什么会导致空指针

7 天前
 SmaliYu

Application 代码大体是这个样子的

public class MyApp extends Application {

    private static MyApp sApp;

    private static SharedPreferences sDefaultSP;

    @Override
    public void onCreate() {
        super.onCreate();
        sApp = this;
        sDefaultSP = PreferenceManager.getDefaultSharedPreferences(this);

    }

    public static SharedPreferences getDefaultSP() {
        return sDefaultSP;
    }

    public static Application get() {
        return sApp;
    }

看回传的日志,在很少数量的用户设备上,某个 Activity.onCreate 调用 getDefaultSP()的时候,会获取到空值,引发崩溃。感觉挺奇怪的,正常系统重建不应该和 Application 有关系啊,即便是整个进程重建,也应该会再走一遍 Application.onCreate 才对啊。

1117 次点击
所在节点    Android
13 条回复
lychee930224
7 天前
我之前也有遇到过同样的问题,确实能观察到很小一部分这样案例。
RightHand
7 天前
因为 jvm 还没有真正的把静态对象初始化完成
SmaliYu
7 天前
@lychee930224 只是希望存键值对的时候不依赖 Context ,结果还是有一些奇怪的问题
lychee930224
7 天前
@SmaliYu 写一个静态方法,然后判空同步取吧
SmaliYu
7 天前
@lychee930224 我下一版会尝试将这两个 SP 移到一个和 Application 无关的类里面(类似 SPManager ),在别的地方初始化,看看还会不会有问题
bjzhou1990
7 天前
看一下具体是什么场景调用为空的,比如 ContentProvider 就比 Application 启动更早
SmaliYu
7 天前
@bjzhou1990 嗯,不过我应用里没有使用 ContentProvider 组件,应该不涉及这个问题
phcbest
6 天前
写成 bylazy 的形式吧,或者直接用 get
val sp1 by lazy {
this.getSharedPreferences("111", Context.MODE_PRIVATE)
}
val sp2: SharedPreferences
get() {
return this.getSharedPreferences("222", Context.MODE_PRIVATE)
}
maokg
6 天前
@phcbest 明显他是 Java ,要实现懒加载还要写又臭又长的代码
HojiOShi
6 天前
@maokg #9

想简单的话,也有有现成的库可以用

https://github.com/RikkaApps/RikkaX/tree/master/lazy
phcbest
6 天前
@maokg 改成 kt 呗,反正可混编,或者用 https://github.com/Blankj/AndroidUtilCode 这个,这个有集成 SP 的工具类,上下文是用反射获得的,如果不想要太多功能就把这个 SP 部分单独拷出来用
zhanlanhuizhang
9 小时 47 分钟前
用 mmkv ,sp 就是这么垃圾。
limiter
5 小时 43 分钟前
有没有其他三方库开了多进程

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://yangjunhui.monster/t/1128909

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX