java在多个片段中使用room数据库

wf82jlnq  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(467)

我有 HomeActivity 带有底部导航栏和5个片段的活动。我想用 RoomDatabase 在所有这些碎片中。我如何实现它?
家庭活动代码:

public class HomeActivity extends AppCompatActivity {

    TextView tvDailyGoalValue;
    SharedPreferences sharedPreferences;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //layout setting
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        BottomNavigationView navView = findViewById(R.id.nav_view);
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_profile, R.id.navigation_notifications)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.fragment3);
        NavigationUI.setupWithNavController(navView, navController);
       sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
       RoomDB roomDB = Room.databaseBuilder(this, RoomDB.class,"dripDB").build();        
    }    
}
q1qsirdb

q1qsirdb1#

我并不是说androidroom的使用是或者应该是复杂的,但是,绝对不是你想象的那么简单;看看你的例子。android开发者花了很多时间试图学习如何使用android架构组件和dagger2使他们的应用程序尽可能好,顺便说一句,这是google推荐的与android room一起使用的api。不过,我还是要回答你的问题。
1.实体
决定要在数据库中使用哪些实体。假设我们这里只有一个实体。比如:

@Entity
class User constructor(
    @ColumnInfo(name = "first_name")
    var firstName: String,

    @ColumnInfo(name = "last_name")
    var lastName: String

    @PrimaryKey(autoGenerate = true)
    var id: Int = 0,
)

2.道类
像这样创建dao类:

/**
 * Provides the abstraction API for accessing data.
 */
@Dao
interface AppDao {

    /**
     * Inserts a new [User].
     * @param user The user to insert.
     */
    @Insert
    suspend fun insertUser(user: User)

    /**
     * Updates the specified [User].
     * @param user The user to update.
     */
    @Update
    suspend fun updateUser(user: User)

    /**
     * Deletes the specified [User] from the database.
     * @param user The user to delete.
     */
    @Delete
    suspend fun deleteUser(user: User)
}

3.数据库类
在单独的类中创建数据库(例如,appdatabase.java)下面是一个好的数据库类的外观:

@Database(entities = [User::class], version = AppDatabase.VERSION)
abstract class AppDatabase : RoomDatabase() {

    /**
     * Returns the DAO for this application.
     * @return The DAO for this application.
     */
    abstract fun getAppDao(): AppDao

    companion object {

        private const val TAG = "AppDatabase"

        const val VERSION = 1
        private const val DATABASE_NAME = "inventory_database.db"

        @Volatile
        private var instance: AppDatabase? = null

        /**
         * Gets and returns the database instance if exists; otherwise, builds a new database.
         * @param context The context to access the application context.
         * @return The database instance.
         */
        fun getInstance(context: Context): AppDatabase =
            instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }

        /**
         * Creates and returns the callback object to execute when the database is first created.
         * @return The callback object to execute when the database is first created.
         */
        private fun appDatabaseCallback(): Callback = object : Callback() {

            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                Log.d(TAG, "Database has been created.")

                // Throws exception
                CoroutineScope(Dispatchers.IO).launch {
                    instance?.getAppDao()?.let { populateDbAsync(it) }
                }
            }

            override fun onOpen(db: SupportSQLiteDatabase) {
                super.onOpen(db)
                Log.d(TAG, "Database has been opened.")
            }
        }

        /**
         * Builds and returns the database.
         * @param appContext The application context to reference.
         * @return The built database.
         */
        private fun buildDatabase(appContext: Context): AppDatabase {
            val filesDir = appContext.getExternalFilesDir(null)
            val dataDir = File(filesDir, "data")
            if (!dataDir.exists())
                dataDir.mkdir()

            val builder =
                Room.databaseBuilder(
                    appContext,
                    AppDatabase::class.java,
                    File(dataDir, DATABASE_NAME).toString()
                ).fallbackToDestructiveMigration()

            // Execute the callback only in DEBUG mode.
            if (BuildConfig.DEBUG) {
                builder.addCallback(appDatabaseCallback())
            }
            return builder.build()
        }

        /**
         * Populates the database when it is first created, as a suspended operation.
         * @param appDao The application DAO to execute queries.
         */
        private suspend fun populateDbAsync(appDao: AppDao) {

            withContext(Dispatchers.IO) {
                // Populate your database here...
            }

        }
    }
}

4.活动和片段
活动

class MainActivity : AppCompatActivity() {

    private lateinit var dao: AppDao

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize the DAO..
        dao = AppDatabase.getInstance(requireContext()).getAppDao()
    }

    // An example of how to execute a dao method in an activity (Again, not recommended)
    private fun insertUser(firstName: String, lastName: String) {
        val user = User(firstName, lastName)

        lifecycleScope.launch { 
            dao.insertUser(user)
        }
    }

    // The rest of the code here...
}

你可以为你的所有活动做同样的事情。
片段

class ExampleFragment : Fragment(R.layout.fragment_example) {

    private lateinit var dao: AppDao

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize the DAO..
        dao = AppDatabase.getInstance(requireContext()).getAppDao()
    }

    // An example of how to execute a dao method in a fragment (Again, not recommended)
    private fun insertUser(firstName: String, lastName: String) {
        val user = User(firstName, lastName)

        lifecycleScope.launch { 
            dao.insertUser(user)
        }
    }

    // The rest of the code here...
}

您可以对所有片段执行相同的操作。

vdzxcuhz

vdzxcuhz2#

您应该为roomdb对象创建一个全局可访问的示例。医生甚至说:
如果应用程序在单个进程中运行,那么在示例化appdatabase对象时应该遵循单例设计模式。每个roomdatabase示例都相当昂贵,您很少需要在一个进程中访问多个示例。
有多种方法可以跨多个活动和片段共享单个对象,例如:
使用匕首和配置 @Singleton 你能做到的 @Inject 在所有相关的活动和片段中。如果你是第一次使用匕首的话,设置匕首有点复杂,但是在专业应用程序中这是通常的选择。
使用经典的java单例设计模式并转换 RoomDB 一个单身汉。
使用自定义 Application 子类,把 RoomDB 示例并将其暴露给任何 Context ,例如。 ((YourCustomApplication)context.getApplication()).getRoomDB() 我认为你最好的选择是1)可扩展性或2)简单性。

相关问题