使用 EncryptedSharedPreferences 时出现 ANR

问题描述 投票:0回答:1

我的应用程序广播接收器中收到 ANR。

来自谷歌控制台的日志 -

Broadcast of Intent { flg=0x14 cmp=in.medibuddy/.receivers.DailyInitHealthReceiver (has extras) }

最近我使用这个库 androidx.security:security-crypto:1.0.0 包含了 EncryptedSharedPreferences。 之后我在谷歌控制台中看到了多个与应用程序相关的ANR。 下面的日志我可以在谷歌控制台中找到。

#00  pc 000000000005589c  /system/lib/libc.so (__ioctl+8)
  #00  pc 0000000000022363  /system/lib/libc.so (ioctl+38)
  #00  pc 000000000003d863  /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+206)
  #00  pc 000000000003e339  /system/lib/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+240)
  #00  pc 000000000003729d  /system/lib/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+36)
  #00  pc 00000000000cacd3  /system/lib/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)+82)
  at android.os.BinderProxy.transactNative (Native method)
  at android.os.BinderProxy.transact (Binder.java:1145)
  at android.security.IKeystoreService$Stub$Proxy.exist (IKeystoreService.java:932)
  at android.security.KeyStore.contains (KeyStore.java:366)
  at android.security.keystore.AndroidKeyStoreSpi.engineContainsAlias (AndroidKeyStoreSpi.java:1037)
  at java.security.KeyStore.containsAlias (KeyStore.java:1293)
  at androidx.security.crypto.MasterKeys.keyExists (MasterKeys.java:137)
  at androidx.security.crypto.MasterKeys.getOrCreate (MasterKeys.java:87)
  at in.medibuddy.util.UserStore.getSecuredPref (UserStore.java:34)
  at in.medibuddy.util.UserStore.getPref (UserStore.java:19)
  at in.medibuddy.MediBuddyApplication.initializeFirebaseAnalytics (MediBuddyApplication.java:211)
  at in.medibuddy.MediBuddyApplication.onCreate (MediBuddyApplication.java:201)
  at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1158)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6304)
  at android.app.ActivityThread.access$1200 (ActivityThread.java:241)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1807)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:214)
  at android.app.ActivityThread.main (ActivityThread.java:7156)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)

任何人都可以帮助我,为什么会发生这种情况?

android broadcastreceiver android-keystore
1个回答
0
投票

这是因为 Android 密钥库实际上不能从主线程调用。

EncryptedSharedPreferences
使用密钥库进行加密。

那么为什么不是主线程呢?

  1. Keystore 负责加密“东西”,这可能会很慢。例如RSA 密钥生成可能需要几秒钟的时间。
  2. 如果您使用 Strongbox(Android 上的 Secure Element 支持的加密货币),则密钥库会特别慢。
  3. 在幕后,密钥库执行磁盘 I/O,我认为这也是主线程的禁忌。

在这个堆栈中,有一个

containsAlias
调用似乎需要一些时间。在幕后,这是执行磁盘 I/O 来搜索密钥。在较旧的(Android 12 之前的)设备上,如果设备上有很多密钥库密钥,我认为此操作可能有点麻烦。

对于 Android U,密钥库 API 现在已注释,以便如果应用程序从主线程调用密钥库 API,StrictMode 会发出警告。看起来这可能尚未公开记录,但这是可以修复的! :)


综上所述...应用程序通常不想使用

EncryptedSharedPreferences
无论如何。例如,由于
EncryptedSharedPreferences
使用密钥库加密,这意味着它们无法在出厂重置后保存或转移到其他设备(例如通过云备份)。当用户抱怨云恢复后他们丢失了设置时,这些事情有时会让开发人员感到惊讶。如果这是您在应用程序中想要的行为,那就去做吧!人们真正想要这种行为并不是非常典型。

还要考虑 Android 已经具有 文件加密。应用程序数据已使用每用户凭证进行加密。如果您的目的是数据永远不会以明文形式存在,那么为首选项添加额外的加密层不一定会改善情况。

© www.soinside.com 2019 - 2024. All rights reserved.