LiveData不会将数据从一个Activity更新到另一个Activity - Android

时间:2017-07-19 17:06:44

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

我有2 Activity viz

  1. 列出Activity
  2. 详情Activity
  3. 列表Activity显示项目列表,单击列表中的项目时会显示详细信息Activity。 在ListActivity我们观察到从数据库中提取提要,一旦我们这样做,我们就会更新用户界面。

    列表页

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

    现在我们有一个DetailActivity页面更新了Feed(项目),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
        }
    
    }
    

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

3 个答案:

答案 0 :(得分:4)

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

<强>问题

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

<强>解决方案

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

答案 1 :(得分:0)

我在同一实体的多个活动中面临同样的问题。对我来说,将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());
}

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

希望得到这个帮助。

答案 2 :(得分:0)

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

sbyte* pinData = (sbyte *)address.ToPointer(); sbyte** ppInData = &pinData;

忘记行:

@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
           }
       }
   }
}