LiveData不将数据从一个活动更新到另一个活动-Android

LiveData不将数据从一个活动更新到另一个活动-Android,android,android-room,android-architecture-components,android-livedata,Android,Android Room,Android Architecture Components,Android Livedata,我有两个活动 列出活动 详细信息活动 列表活动显示项目列表,单击列表中的项目时,将显示详细信息活动。 在ListActivity中,我们观察如何从数据库获取提要,一旦我们这样做,我们就会更新UI 列表页 feedViewModel.getFeeds().observe(this, Observer { feeds -> feeds?.apply { feedAdapter.swap(feeds) feedAdapter.notif

我有两个
活动

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

    列表页

    feedViewModel.getFeeds().observe(this, Observer { feeds ->
          feeds?.apply {
                feedAdapter.swap(feeds)
                feedAdapter.notifyDataSetChanged()
          }
    })
    
    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            feedViewModel.setFeedId(id)
            feedViewModel.updateFeed()
    }
    
    现在我们有了一个
    DetailActivity
    页面,该页面更新提要(项目),并且
    Activity
    已经完成,但是更改没有反映在
    ListActivity

    详细信息页面

    feedViewModel.getFeeds().observe(this, Observer { feeds ->
          feeds?.apply {
                feedAdapter.swap(feeds)
                feedAdapter.notifyDataSetChanged()
          }
    })
    
    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            feedViewModel.setFeedId(id)
            feedViewModel.updateFeed()
    }
    
    提要视图模型

    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
        }
    
    }
    
    类FeedViewModel(应用程序:应用程序):AndroidViewModel(应用程序){
    private val feedRepository=feedRepository(FeedService.create(getToken(getApplication())),
    DatabaseCreator(应用程序).database.feedDao()
    /**
    *保存提要的id
    */
    私有val feedId:MutableLiveData=MutableLiveData()
    /**
    *完整的提要列表
    */
    私有变量提要:LiveData=MutableLiveData()
    /**
    *基于实时提要id的特定提要
    */
    私有变量提要:LiveData
    初始化{
    feeds=feedRepository.feeds
    feed=Transformations.switchMap(feedId){id->
    feedRepository.getFeed(id)
    }
    }
    /**
    *获取提要列表
    */
    fun getFeeds()=源
    fun setFeedId(id:Long){
    feedId.value=id
    }
    /**
    *更新提要
    */
    fun updateFeed(){
    feedRepository.updateFeed()文件
    }
    /**
    *根据提要id获取提要
    */
    fun getFeed():LiveData{
    回馈
    }
    }
    

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

    经过大量的调查和其他问题的一些想法。我解决了这个问题

    问题

    feedViewModel.getFeeds().observe(this, Observer { feeds ->
          feeds?.apply {
                feedAdapter.swap(feeds)
                feedAdapter.notifyDataSetChanged()
          }
    })
    
    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            feedViewModel.setFeedId(id)
            feedViewModel.updateFeed()
    }
    
    数据库创建者(应用程序).database.feedDao()的没有创建数据库的单例实例,因为第一个
    活动
    有另一个实例,
    LiveData
    正在侦听更改,第二个
    活动
    有另一个实例,在更新数据后,回调被忽略

    解决方案


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

    我在同一实体的多个活动中面临着同样的问题。对我来说,将Room数据库实例作为一个单例进行编码非常有用,例如:

    例如:

    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扩展为上下文参数):

    现在,在我的例子中,每次我在配置活动中编辑一个值时,它都会反映在其他活动中


    希望这有帮助。

    我有完全相同的问题,但是我已经将DB和DAO的实例注释为单例。你改变了什么?顺便说一下,我用的是匕首2。如果你想了解更多信息,这里是我发布的问题: