自定义SharedPreferences性能优化:实例化与静态类选型咨询
嗨,我来聊聊这个问题~先拆解下你的顾虑,再分析静态类方案的合理性,以及更稳妥的替代思路:
先说说频繁实例化的性能影响
其实你不用太担心频繁实例化UserSession的性能损耗。因为SharedPreferences本身是系统维护的单例对象——同一个名字的SP,无论你调用多少次getSharedPreferences(),返回的都是同一个实例。而你的UserSession只是对这个SP的封装,每次new对象的开销只是创建一个持有Context和SP引用的简单对象,这种开销在Android里几乎可以忽略不计。真正的问题其实是代码冗余:每次都要写实例化的代码,显得繁琐。
静态类方案的合理性与风险
把UserSession改成静态类确实能解决代码冗余的问题,不用每次new对象就能直接调用静态方法,但这里有个致命的坑:内存泄漏!
如果你的静态方法里持有了Activity的Context(比如你之前传的getActivity()),那么当Activity被销毁时,静态引用会一直持有这个Activity的实例,导致它无法被GC回收,最终引发内存泄漏。
如果一定要用静态类,必须确保使用Application Context——它的生命周期和应用一致,不会因为页面销毁而被回收。比如可以这样实现:
public class UserSession { private static SharedPreferences sharedPreferences; // 建议在Application的onCreate里初始化一次 public static void init(Context context) { sharedPreferences = context.getApplicationContext() .getSharedPreferences("customSharedpreferences", Context.MODE_PRIVATE); } // 静态Getter/Setter示例 public static String getUserName() { return sharedPreferences.getString("user_name", ""); } public static void setUserName(String userName) { sharedPreferences.edit().putString("user_name", userName).apply(); } }
然后在你的Application类里调用UserSession.init(this);,之后就能在任意地方直接调用静态方法了。但静态类的缺点是灵活性差,比如无法继承、无法多实例(虽然你也不需要),而且如果忘记初始化会抛出空指针异常。
更推荐的方案:单例模式
相比静态类,单例模式既能避免频繁实例化的代码冗余,又能安全地管理Context,还保留了类的面向特性。比如线程安全的双重检查锁单例:
public class UserSession { private static volatile UserSession instance; private final SharedPreferences sharedPreferences; // 私有构造方法,禁止外部直接实例化 private UserSession(Context context) { // 使用Application Context彻底避免内存泄漏 sharedPreferences = context.getApplicationContext() .getSharedPreferences("customSharedpreferences", Context.MODE_PRIVATE); } // 线程安全的单例获取方法 public static UserSession getInstance(Context context) { if (instance == null) { synchronized (UserSession.class) { if (instance == null) { instance = new UserSession(context); } } } return instance; } // 你的Getter/Setter方法示例 public String getUserToken() { return sharedPreferences.getString("user_token", ""); } public void setUserToken(String token) { sharedPreferences.edit().putString("user_token", token).apply(); } }
使用的时候只需要调用UserSession.getInstance(getActivity()),第一次调用会初始化实例,之后每次返回的都是同一个对象,既简洁又安全。
性能对比总结
不管是频繁实例化、静态类还是单例模式,性能上几乎没有差别——因为核心的SharedPreferences实例都是系统维护的单例,三种方案最终都是操作同一个SP对象。差别主要在代码优雅度和内存安全性上:
- 频繁实例化:性能无问题,但代码冗余
- 静态类:代码简洁,但需注意Context泄漏和初始化问题
- 单例模式:兼顾简洁、安全和面向对象特性,是最优解
内容的提问来源于stack exchange,提问作者Ritu

