【问题标题】:Call Application context in Activity在 Activity 中调用应用程序上下文
【发布时间】:2021-01-29 18:14:28
【问题描述】:

我正在尝试从 Android 上的活动调用我的数据库(使用 Room 制作),但它需要应用程序上下文,如果我在 Activity 的构造函数中传递“应用程序:应用程序”,则构建崩溃并告诉我:

java.lang.Class 没有零参数构造函数

这是我的代码:

class PhotoActivity(application: Application) : AppCompatActivity() {


    private val pictureDao = PictureDatabase.getDatabase(app)

//Some code ....

我需要一个上下文,我试图传递“this”,但又遇到了另一个错误

谁能帮帮我,我是这项技术的初学者

编辑:

这是我的数据库类,只是为了向您展示我为什么需要应用程序上下文


@Database(entities = [Picture::class], version = 1, exportSchema = false)
abstract class PictureDatabase : RoomDatabase(){

    abstract fun pictureDao() : PictureDao

     companion object{
        @Volatile
        private var INSTANCE : PictureDatabase? = null

        fun getDatabase(context: Context): PictureDatabase {
            if(INSTANCE == null){
                synchronized(this){
                    INSTANCE = Room.databaseBuilder(
                            context.applicationContext,
                            PictureDatabase::class.java,
                            "pictures.db"
                    ).build()
                }
            }
            return INSTANCE!!
        }
    }

}

【问题讨论】:

  • 感谢@Reza 提供指向另一个问题的链接,我学到了一些东西,但还不足以解决我的问题..
  • 好吧,我的朋友删除应用程序:来自活动构造器的应用程序。通常活动和片段应该有空的构造函数,因为android会为我们实例化它们,我们不负责创建它们

标签: android android-room android-database


【解决方案1】:

Activity 是我们在清单中声明然后使用intent 启动它们的东西,但是,活动实例的创建是由system 而不是我们完成的。使用constructor 创建一个实例,但如果是我们,那么我们可以有任意数量的重载构造函数。但是系统只需要一个构造函数,它应该是一个零参数的构造函数,并且应该是公共的。

所以你的活动签名

class PhotoActivity(application: Application) : AppCompatActivity() {

应该改为

class PhotoActivity() : AppCompatActivity() {

要调用fun getDatabase(context: Context): PictureDatabase,您可以从activity 传递this。 Activity 是 Context 的间接子代。

你可以通过以下方式做到这一点,

  1. private val pictureDao by lazy{ PictureDatabase.getDatabase(this) }
  2. private lateinit var pictureDao:PictureDatabase 然后在onCreate()初始化它
final override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.your_layout)
        PictureDatabase.getDatabase(this)
        //your logic goes here
   }

【讨论】:

  • 我了解它现在是如何工作的,非常感谢这个答案,它有效!
【解决方案2】:

首先创建一个ViewModel,在ViewModel里面你可以访问你的Dao,pictureDao。

 class PictureViewModel(application: Application) : 
   AndroidViewModel(application) {


     val pictureDao: PictureDao

     init {
         pictureDao = 
        PictureDatabase.getDatabase(application).pictureDao()
   
         }



      }

然后在您的活动中,初始化 ViewModel。并访问你的道。

 class PhotoActivity : AppCompatActivity() {

   private lateinit var pictureViewModel: PictureViewModel

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

    pictureViewModel = 
   ViewModelProviders.of(this).get(PictureViewModel::class.java)

   //You can now access your Dao class here:
   val pictureDao = pictureViewModel.pictureDao




    
 }
 }

【讨论】:

    【解决方案3】:

    您不应将Application 传递给构造函数。您应该将applicationContext 传递给getDatabase(),例如private val pictureDao = PictureDatabase.getDatabase(applicationContext)

    【讨论】:

    • 我有一个类型不匹配错误:应用程序是预期的
    • 我将编辑我的帖子,让您了解我为什么需要应用程序上下文
    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2011-04-24
    相关资源
    最近更新 更多