如何正确配置SafeRoom 0.0.4?集成Safe-room库遇未知错误求助
Hey there! Let's break down how to properly configure SafeRoom 0.0.4 and troubleshoot that unknown error you're hitting in the Google Todo-MVP project.
一、Correct Configuration Steps for SafeRoom 0.0.4
First, let's make sure your setup is right from the start:
Add Matching Dependencies
SafeRoom is an extension of Room, so you must keep Room core and SafeRoom versions in sync. For 0.0.4, pair it with Room 2.2.5 (the compatible stable release). Add these to your module-levelbuild.gradle:dependencies { // Room core implementation "androidx.room:room-runtime:2.2.5" kapt "androidx.room:room-compiler:2.2.5" // SafeRoom encryption implementation "net.sqlcipher:sqlcipher-android:4.4.0" implementation "androidx.security:security-crypto:1.0.0" implementation "androidx.room:room-safektx:2.2.5" }Note: Using mismatched versions (e.g., Room 2.3.0 with SafeRoom 2.2.5) is a common source of initialization crashes.
ProGuard Rules (If Enabled)
Prevent SafeRoom and SQLCipher classes from being obfuscated by adding these rules to yourproguard-rules.pro:-keep class net.sqlcipher.** { *; } -keep class androidx.room.safe.** { *; }Initialize SQLCipher Native Libraries
In your application class, load SQLCipher's native binaries before using the database:class TodoApp : Application() { override fun onCreate() { super.onCreate() net.sqlcipher.database.SQLiteDatabase.loadLibs(this) } }Don't forget to declare this class in your
AndroidManifest.xml.
二、Troubleshooting Integration Errors in Todo-MVP (Dagger2 + RxJava)
Looking at your code snippet, it looks like you were on the right track—let's finish the implementation and fix common pitfalls:
First, Correct Your Database Implementation
Here's the complete, working version of your TodoDatabase class:
@Database(entities = [Task::class], version = 1) abstract class TodoDatabase : RoomDatabase() { abstract fun taskDao(): TaskDao companion object { private val lock = Any() private var INSTANCE: TodoDatabase? = null fun getInstance(context: Context): TodoDatabase { synchronized(lock) { if (INSTANCE == null) { val password = "password123".toCharArray() val encryptionFactory = SafeHelperFactory(password) INSTANCE = Room.databaseBuilder( context.applicationContext, TodoDatabase::class.java, "Tasks.db" ) .openHelperFactory(encryptionFactory) .build() } return INSTANCE!! } } } }
Common Error Causes & Fixes
Dagger2 Injection Misconfiguration
In Todo-MVP, you're using Dagger2 to provide dependencies—make sure yourDatabaseModulecorrectly provides the encrypted database instance (avoid double-initialization):@Module class DatabaseModule { @Provides @Singleton fun provideTodoDatabase(context: Context): TodoDatabase { return TodoDatabase.getInstance(context) } @Provides @Singleton fun provideTaskDao(database: TodoDatabase): TaskDao { return database.taskDao() } }Ensure your component includes this module and injects the DAO correctly into your presenters.
Unencrypted Database Migration Issues
If you previously ran the app with an unencryptedTasks.db, switching to SafeRoom will fail—SafeRoom can't migrate unencrypted databases directly. For testing, clear app data to delete the old database. For production, you'll need to export old data, create a new encrypted database, and re-import the data.Missing SQLCipher Initialization
If you skipped loading SQLCipher libraries in your Application class, you'll get anUnsatisfiedLinkError. Double-check thatSQLiteDatabase.loadLibs(this)is called before any database operations.Permission Problems (Android 10+)
If your database is stored in external storage, Android 10+ Scoped Storage may block access. Use the default internal storage path (which Room uses by default) to avoid this issue.
Debug Tip: Capture Exceptions
To get the exact error message, wrap your database initialization in a try-catch block and log the stack trace:
fun getInstance(context: Context): TodoDatabase { synchronized(lock) { if (INSTANCE == null) { try { val password = "password123".toCharArray() val encryptionFactory = SafeHelperFactory(password) INSTANCE = Room.databaseBuilder( context.applicationContext, TodoDatabase::class.java, "Tasks.db" ) .openHelperFactory(encryptionFactory) .build() } catch (e: Exception) { e.printStackTrace() // Log to Crashlytics or show user feedback here } } return INSTANCE!! } }
内容的提问来源于stack exchange,提问作者Douglas Mesquita

