在应用程序启动时,我应该如何/应该在哪里初始化诸如数据库创建,从API等加载资源等的内容?
我目前正在使用Android Studio创建一个Android应用程序,并且关于最初的“ Quitt”的方法是什么,我有一个或两个问题。
截至目前,我在ongreate
MainActivity 的方法中进行初始化,该方法也用作“主”/“启动器”活动。
初始化包括
- 创建一个房间数据库,以后将在
- 关于数据库的创建/获取,即使已经创建了一次数据库后,下面的书面代码也有效以获取实例对象。这让我认为也许我不应该构建另一个名字相同的人,而是从某个地方拿出来?同时,似乎
databaseBuilder()
似乎正在返回现有实例(如果存在)...因此,代码无论如何都可以使用,但是合适吗?
- 关于数据库的创建/获取,即使已经创建了一次数据库后,下面的书面代码也有效以获取实例对象。这让我认为也许我不应该构建另一个名字相同的人,而是从某个地方拿出来?同时,似乎
- 根据用户的电话模式将主题模式设置为亮或黑暗,具体化
- 了我正在使用的Android Studio库/API初始化资源。
我有一种感觉以这种方式初始化事物,在这个地方(在主动行动中占用)是不合适的,它可以(应该?)以其他方式和其他方式进行。所以我的问题是我应该在哪里/应该在哪里进行此类内容的初始化
?
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//applicationContext.deleteDatabase("database-name")
// Create the database
val achievementDao = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,"database-name"
).build().achievementDao()
// Just some random "test" code
GlobalScope.launch {
achievementDao.insertAll(Achievement("title1", "desc1", "date1", "false"))
achievementDao.insertAll(Achievement("title2", "desc2", "date2", "true"))
Log.i("database", achievementDao.getAll().toString())
Log.i("database", achievementDao.getAllComplete().toString())
Log.i("database", achievementDao.getAllIncomplete().toString())
}
// Set relevant theme depending on phone's mode (LIGHT or DARK)
val currentNightMode = (resources.configuration.uiMode
and Configuration.UI_MODE_NIGHT_MASK)
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {
// Night mode is not active
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
Configuration.UI_MODE_NIGHT_YES -> {
// Night mode is active
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
Configuration.UI_MODE_NIGHT_UNDEFINED -> { }
}
// Load in resources
World.init(applicationContext)
// ...
}
// ...
I am currently creating an Android application using Android Studio and I have a question or two regarding what the most appropriate way of initializing "stuff" is.
As of right now I do the initializing in the onCreate
method of the MainActivity
which also serves as the "main"/"launcher" activity.
The initializing consists of
- creating a room-database that will be used later on
- Regarding the creating/fetching of the database, seemingly the written code below works to get the instance object even after the database has already been created once. This leaves me to think that perhaps I shouldn't be building another one with the same name but instead fetch it from somewhere? At the same time seemingly the
databaseBuilder()
seems to be returning the existing instance if it exists... so the code works anyway but is it appropriate?
- Regarding the creating/fetching of the database, seemingly the written code below works to get the instance object even after the database has already been created once. This leaves me to think that perhaps I shouldn't be building another one with the same name but instead fetch it from somewhere? At the same time seemingly the
- setting the theme mode to light or dark depending on the user's phone mode
- initializing resources from an Android Studio library/API that I am using.
I have a feeling initializing things in this way and in this place (onCreate in MainActivity) is inappropriate and it can (should?) be done elsewhere and in some other way. So my question is How/where should I be doing the initializing of stuff like this?
MainActivity.kt
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//applicationContext.deleteDatabase("database-name")
// Create the database
val achievementDao = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,"database-name"
).build().achievementDao()
// Just some random "test" code
GlobalScope.launch {
achievementDao.insertAll(Achievement("title1", "desc1", "date1", "false"))
achievementDao.insertAll(Achievement("title2", "desc2", "date2", "true"))
Log.i("database", achievementDao.getAll().toString())
Log.i("database", achievementDao.getAllComplete().toString())
Log.i("database", achievementDao.getAllIncomplete().toString())
}
// Set relevant theme depending on phone's mode (LIGHT or DARK)
val currentNightMode = (resources.configuration.uiMode
and Configuration.UI_MODE_NIGHT_MASK)
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {
// Night mode is not active
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
Configuration.UI_MODE_NIGHT_YES -> {
// Night mode is active
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
Configuration.UI_MODE_NIGHT_UNDEFINED -> { }
}
// Load in resources
World.init(applicationContext)
// ...
}
// ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我希望您在custom
application
类中执行此任务。这是您可以创建它的方式:myApplication.kt 或您想要的任何东西。
Application
onCreate()
方法中,您可以完成所有任务以进行初始化。要了解有关应用程序类的更多信息,请参阅 this 网站。
I'd prefer you to do this task in the custom
Application
class. This is how you can create it:MyApplication.kt
or anything you want.Application
onCreate()
method, you can do all the tasks for your initialisation.To know more about Application class, refer to this site.
构建数据库时,实际上并不是创建数据库。它构建一个实例,该实例将在访问数据库时打开或创建数据库(通常是通过DAO,但可以否则可以完成)。
因此,在您的情况下,只有在
AchievementDao.Intertall(Achievement(“ title1”,“ desc1”,“ date1”,“ false”,“ false”))
运行时,数据库是创建数据库的。不走得太深。
@database
注释的类实例将查看是否存在数据库(名为 database-name 的文件)(位置 data/data/data/data/databases/database-name < /em>)。如果文件不存在,则将创建数据库(因此文件)。如果存在,则将通过基础SQLITE API访问/打开。因此,您访问数据库,应用程序或第一个活动的确并不重要(进一步阅读并欺骗了拨打回调,很简单都无关紧要)。
但是,,您确实需要小心,因为每当运行应用程序或处理冲突时,您都不会无意中添加数据(例如,可以通过
忽略唯一的约束。 onconflict =
@insert
的参数)。您可能希望考虑的是使用
ongreate
回调。这只能在数据库的寿命中运行一次(正如它首先创建数据库时所说的那样),因此仅添加了一次添加的数据(没有资源浪费的尝试添加数据仅忽略数据等) ,缺点是您无法使用DAO(在此阶段它们将无法完全实例化)。相反,您需要使用 supportsqlitedatabase 传递给 回调的方法以及可用的方法,例如execsql,insert等。请参阅 https://developer.android.com/reference/androidx/room/room/room/roomdatabase.callback
另一个选项是利用一个预装数据库,其中数据库将某些数据放入中资产文件夹(不必拥有数据,但没有一些浪费)。在这里,您将使用
.createfromasset
方法/函数添加到databaseBuilder
的调用中。如果有大量数据,这是可取的,而不是批量代码When you build the database, it doesn't in fact create the database. It builds an instance that will open or create the database when it is accessed (typically via a Dao, but can be done otherwise).
So in your case the database is only created when
achievementDao.insertAll(Achievement("title1", "desc1", "date1", "false"))
runs.Without going in too deep. The
@Database
annotated class instance will see if the database (the file named database-name) exists (at location data/data/databases/database-name). If the file does not exist then the database (and therefore the file) will be created. If it exists, then it will be accessed/opened via the underlying SQLite API.As such it doesn't really matter where you access the database, application or the first activity (reading further and implemnting the onCreate Callback, it simple does not matter where at all).
However, you do need to be careful in that you don't inadvertently keep adding the data whenever the App is run, or that you handle conflicts (e.g. a unique constraint can be ignored via the
onConflict =
parameter of an@Insert
).What you may well wish to consider, is using the
onCreate
callback. This will only run once for the lifetime of the database (as it says when the database is first created), thus the data added is added once and only the once (no resource wasteful attempts to add data only for it to be ignored etc), the drawback is that you can't use the Dao's (they will not have been fully instantiated at this stage). Rather you need to use the SupportSQLiteDatabase passed to theonCreate
method of the callback, and the methods available to it such as execSQL, insert etc.see https://developer.android.com/reference/androidx/room/RoomDatabase.Callback
Another option is to utilise a pre-packaged database, where the database, with some data is placed into the assets folder (doesn't have to have data but without it's a bit of a waste). Here you would use the
.createFromAsset
method/function added to the invocation of thedatabaseBuilder
. This is preferable if there is a large amount of data, rather than bulking up the code