尝试初始化共享首选项单例类时,我们收到IllegalStageException,但我不知道是什么原因引起的。
在座的人可以告诉我这可能是什么原因吗?
注意:这仅在Pie上发生
以下是Google Play控制台中的报告(崩溃未在Crashlytics中显示):
java.lang.RuntimeException:
at android.app.ActivityThread.handleBindApplication (ActivityThread.java:5876)
at android.app.ActivityThread.access$1100 (ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1650)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:193)
at android.app.ActivityThread.main (ActivityThread.java:6669)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:858)
Caused by: java.lang.IllegalStateException:
at android.app.ContextImpl.getSharedPreferences (ContextImpl.java:419)
at android.app.ContextImpl.getSharedPreferences (ContextImpl.java:404)
at android.content.ContextWrapper.getSharedPreferences (ContextWrapper.java:174)
at com.nbc.news.utils.SharedPreferences.<init> (SharedPreferences.java:27)
at com.nbc.news.utils.SharedPreferences.init (SharedPreferences.java:44)
at com.nbc.news.NbcNews.onCreate (NbcNews.java:122)
at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1154)
at android.app.ActivityThread.handleBindApplication (ActivityThread.java:5871)
这是初始化代码:
private android.content.SharedPreferences sharedPreferences;
private static SharedPreferences instance;
private SharedPreferences(Context context) {
Context appContext = context.getApplicationContext();
sharedPreferences = appContext.getSharedPreferences(context.getString(R.string.database_name), Context.MODE_PRIVATE); // <- this is line #27
}
public android.content.SharedPreferences getPreference(){
return sharedPreferences;
}
public static SharedPreferences getInstance() {
if (instance == null) {
throw new RuntimeException("SharedPreferences must be initialized with context prior to use");
}
return instance;
}
public static void init(Context context) {
if (instance == null) {
instance = new SharedPreferences(context); // <- this is line #44
}
}
答案 0 :(得分:3)
我只发现了一个或两个拼图碎片,这可能会有所帮助:source code of ContextImpl有两个IllegalStateException
,其中一个来自426-454行中的方法getSharedPreferences()
。
“直到用户解锁后,凭据加密存储中的SharedPreferences才可用”
此IllegalStateException
是从if
块引发的,仅当目标SDK版本为Oreo或更高版本时才会执行
if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
if (isCredentialProtectedStorage()
&&
!getSystemService(UserManager.class).isUserUnlockingOrUnlocked(UserHandle.myUserId())) {
throw new IllegalStateException("SharedPreferences in credential encrypted "
+ "storage are not available until after user is unlocked");
}
}
在网络上搜索isCredentialProtectedStorage()
导致我进入FileBasedEncryption。
由于我不知道您应用程序的工作流程的详细信息,因此我只能建议确保在设备锁定时,该应用程序不会尝试访问受保护的文件。
答案 1 :(得分:1)
您必须尝试在SharedPreferences
之后和LOCKED_BOOT_COMPLETED
之前访问BOOT_COMPLETED
,这是自牛轧糖/ API 24以来不允许的,除非您将首选项迁移到设备保护的存储。
这里有2个选项:
LOCKED_BOOT_COMPLETED
操作和android:directBootAware
标志。这样,您的应用将等到BOOT_COMPLETED
(当用户解锁设备时),然后再尝试访问SharedPreferences
。SharedPreferences
之后和LOCKED_BOOT_COMPLETED
之前访问BOOT_COMPLETED
,请确保将偏好设置迁移到设备保护存储,并在调用{{ 1}}。有关官方文档中第二个选项的更多详细信息:Support Direct Boot mode
答案 2 :(得分:0)
尝试将 App Center 初始化从 Application 类移动到 MainActivity。这会帮助你。我们必须在应用准备好(BootCompleted)后才调用 Sharepreference。