【问题标题】:LiveData not updating data from one Activity to another Activity - AndroidLiveData 没有将数据从一个 Activity 更新到另一个 Activity - Android
【发布时间】:2017-07-19 17:06:44
【问题描述】:

我有 2 个Activity

  1. 列表Activity
  2. 详情Activity

列表Activity 显示项目列表,详细信息Activity 在单击列表中的项目时显示。 在ListActivity 中,我们观察到从数据库中获取提要,一旦这样做,我们就会更新 UI。

列表页面

feedViewModel.getFeeds().observe(this, Observer { feeds ->
      feeds?.apply {
            feedAdapter.swap(feeds)
            feedAdapter.notifyDataSetChanged()
      }
})

现在我们有一个 DetailActivity 页面,它更新了提要(项目),Activity 已完成,但更改未反映在 ListActivity 中。

详情页面

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        feedViewModel.setFeedId(id)
        feedViewModel.updateFeed()
}

Feed 视图模型

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


    private val feedRepository = FeedRepository(FeedService.create(getToken(getApplication())),
            DatabaseCreator(application).database.feedDao())

    /**
     * Holds the id of the feed
     */
    private val feedId: MutableLiveData<Long> = MutableLiveData()

    /**
     * Complete list of feeds
     */
    private var feeds: LiveData<Resource<List<Feed>>> = MutableLiveData()

    /**
     * Particular feed based upon the live feed id
     */
    private var feed: LiveData<Resource<Feed>>

    init {
        feeds = feedRepository.feeds
        feed = Transformations.switchMap(feedId) { id ->
            feedRepository.getFeed(id)
        }
    }

    /**
     * Get list of feeds
     */
    fun getFeeds() = feeds

    fun setFeedId(id: Long) {
        feedId.value = id
    }

    /**
     * Update the feed
     */
    fun updateFeed() {
        feedRepository.updateFeed()
    }

    /**
     * Get feed based upon the feed id
     */
    fun getFeed(): LiveData<Resource<Feed>> {
        return feed
    }

}

为简单起见,一些代码已被抽象出来。如果需要,我可以添加它们来跟踪问题

【问题讨论】:

    标签: android android-room android-architecture-components android-livedata


    【解决方案1】:

    经过大量调查和来自this answer 的一些想法来自另一个问题。我想通了。

    问题

    DatabaseCreator(application).database.feedDao() 没有创建数据库的单例实例,因为第一个 Activity 有另一个实例,LiveData 正在侦听更改,第二个 Activity 有另一个实例,在更新数据后回调是忽略。

    解决方案

    使用 Dagger 或任何其他依赖注入来确保仅创建 DB 和 DAO 的单个实例。

    【讨论】:

    • 我有完全相同的问题,但是我已将 DB 实例和 DAO 注释为单例。你改变了什么?顺便说一句,我正在使用 Dagger 2。如果您想了解更多信息,这里是我发布的问题:stackoverflow.com/questions/48267724/…
    【解决方案2】:

    我在同一实体的多个活动中面临同样的问题。对我来说,将 Room Database 实例编码为 Singleton 很有用,例如:this (step 5)

    例子:

    public abstract class MyDatabase extends RoomDatabase {
        private static MyDatabase mMyDatabase;
        public static MyDatabase getInstance(Context context) {
            if(mMyDatabase==null){
                mMyDatabase = Room.databaseBuilder(context.getApplicationContext(), MyDatabase.class, "app_database").build();
                return mMyDatabase;
            }
        }
    }
    

    在您拥有的每个 ViewModel 中(类从 AndroidViewModel 扩展为 Context 参数):

        public MyViewModel(@NonNull Application application) {
            super(application);
            mMyDatabase = MyDatabase.getInstance(application.getApplicationContext());
    }
    

    现在,就我而言,每次我在配置活动中编辑一个值时,它都会反映在其他活动中。

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。在下面的代码中,我忘记了一行,单例没有工作(问题与主要答案相同)。

      @Database(entities = [SleepNight::class], version = 1, exportSchema = false)
      abstract class SleepDatabase : RoomDatabase() {
      
         abstract val sleepDatabaseDao: SleepDatabaseDao
      
         companion object {
      
             @Volatile
             private var INSTANCE: SleepDatabase? = null
      
             fun getInstance(context: Context): SleepDatabase {
                 synchronized(this) {
                     var instance = INSTANCE
      
                     if (instance == null) {
                         instance = Room.databaseBuilder(
                                 context.applicationContext,
                                 SleepDatabase::class.java,
                                 "sleep_history_database"
                         )
                                 .fallbackToDestructiveMigration()
                                 .build()
                         INSTANCE = instance
                     }
                     return instance
                 }
             }
         }
      }
      

      忘记的行:

      INSTANCE = instance
      

      【讨论】:

        猜你喜欢
        • 2017-04-05
        • 2017-12-28
        • 1970-01-01
        • 2012-03-30
        • 2019-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多