java.lang.IllegalStateException: SharedPreferences in credential encrypted storage are not available until after user is unlocked
一、问题背景
在一个AndroidO的平台上,将一个使用SharedPreference应用的TargetSdk设置为26后,如果在TV刚开机的时候,就会出现以上的crash问题,导致应用崩溃(应用mode为 private,android N后可正常支持)。
查看源码(如下图):
二、问题原因
通过看源码可以分析出,出现该问题的原因:targetSdk为androidO及以上、访问内部存储空间、当前设备处于锁定状态。在Android8上,在TV刚开机处于LOCKED 状态时,应用此时不可访问内部存储空间。对于TV的锁定状态,咨询了相关的同事,Android系统关开机后,都会进入LOCKED 状态。手机这时需要解锁才会进入UNLOCKED 状态。对于TV,会自动在开机后由LOCKED 状进入UNLOCKED 状态。
三、目前解决方法
1、 由于该应用只有在targetSdk为androidO及以上的时候才会出现,因此,可以将应用的targetSdk的版本改到26以下可规避该问题。
2、 TV刚开机的时,在为LOCKED 状态时避免拉起使用SharedPreference的应用,避免产生该问题。
四、内部存储
了解该问题时,发现一篇博文对于内部存储的说明很好,摘到这里:
注意内部存储不是内存。内部存储位于系统中很特殊的一个位置,如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。从技术上来讲如果你在创建内部存储文件的时候将文件属性设置成可读,其他app能够访问自己应用的数据,前提是他知道你这个应用的包名,如果一个文件的属性是私有(private),那么即使知道包名其他应用也无法访问。内部存储空间十分有限,因而显得可贵,另外,它也是系统本身和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机也就无法使用了。所以对于内部存储空间,我们要尽量避免使用。Shared Preferences和SQLite数据库都是存储在内部存储空间上的。内部存储一般用Context来获取和操作。
参考文章连接 :
https://www.jianshu.com/p/aa33c2458729
https://blog.csdn.net/sjz4860402/article/details/80812750