SharedPreferences contains方法始终返回true,卸载重装后仍判定非首次登录
这个问题的核心原因是Android系统的自动应用数据备份机制在部分设备上恢复了你的SharedPreferences数据,导致卸载重装后之前的登录状态依然存在。
为什么会出现这个现象?
从Android 6.0(API Level 23)开始,系统默认开启了自动应用数据备份功能,会将应用的SharedPreferences、SQLite数据库等数据备份到Google云端或者厂商自己的云服务(比如三星的Galaxy Cloud)。当你卸载应用后重新安装时,系统会自动恢复这些备份的数据,这就导致你的Login.LOGIN_PREF文件里依然保留着之前的Login.REMEMBER_USER键值,触发了NetworkManager.login的逻辑。
而这个问题只在部分设备(比如Galaxy S6)出现的原因可能有这些:
- 这些设备的系统版本在API 23及以上,且默认开启了自动备份;
- 部分厂商(如三星)的定制系统加强了备份策略,即使你没有手动开启云端备份,也可能默认备份了应用数据;
- 低版本Android设备(API <23)默认没有这个自动备份机制,所以不会出现该问题。
如何解决这个问题?
你可以通过以下几种方式来处理:
1. 全局关闭应用自动备份
在AndroidManifest.xml的<application>标签中添加android:allowBackup="false",彻底关闭应用的自动备份功能:
<application android:allowBackup="false" ...> ... </application>
这个方法简单直接,但会关闭所有应用数据的备份,如果你有需要备份的其他数据,可能不太合适。
2. 精细控制备份内容(推荐)
创建一个备份规则文件,指定不备份你的登录状态SharedPreferences:
- 在
res/xml目录下创建backup_rules.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <full-backup-content> <!-- 排除登录状态的SharedPreferences文件 --> <exclude domain="sharedpref" path="Login.LOGIN_PREF.xml" /> </full-backup-content>
- 然后在
AndroidManifest.xml的<application>标签中引用这个规则:
<application android:fullBackupContent="@xml/backup_rules" ...> ... </application>
这样既能保留其他数据的备份功能,又能避免登录状态被恢复。
3. 额外添加首次安装校验逻辑
在你的判断逻辑中增加一个与应用安装时间相关的校验,比如存储应用的首次安装时间,卸载重装后这个时间会重置,以此来准确判断是否是首次登录:
SharedPreferences prefs = getSharedPreferences(Login.LOGIN_PREF, Context.MODE_PRIVATE); long firstInstallTime = getPackageManager().getPackageInfo(getPackageName(), 0).firstInstallTime; long savedInstallTime = prefs.getLong("FIRST_INSTALL_TIME", 0); // 同时校验登录状态和安装时间 if(savedInstallTime == firstInstallTime && prefs.contains(Login.REMEMBER_USER) && prefs.getBoolean(Login.REMEMBER_USER, false)) { NetworkManager.login(SplashActivity.this, SplashActivity.this); } else { // 更新存储的安装时间 prefs.edit().putLong("FIRST_INSTALL_TIME", firstInstallTime).apply(); Intent in = new Intent(SplashActivity.this, Login.class); startActivity(in); finish(); }
这个方法可以作为额外的保障,即使备份机制恢复了SharedPreferences数据,也能通过安装时间的差异判断出是重装后的首次启动。
内容的提问来源于stack exchange,提问作者Keselme

