2

I'm using room to communicate data fetched by a foreground Location service with the an activity. The service connects to the viewmodel and does insert data, the activity however does not receive updated LiveData from the viewmodel, it is however able to fetch a LiveData> object at the begining, with accurate size when restarting the app. What am I missing here? I need to insert new data into the db, so if I do need to use MutableLiveData in the service and postValue, then I would have to post the entire list everytime...

Activity.java


@Override
protected void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );

    setContentView( R.layout.track_activity );

    mViewModel = ViewModelProviders.of( this ).get( ViewModel.class );

    mViewModel.getAllData().observe( this, ( @Nullable final <List<eData>> data ) -> {

        if ( data!= null )
            Log.d("DATACOUNT", String.valueOf(data.size()) );

    } );
}

Service.java

@Override
public void onCreate() {
    super.onCreate();

    AppDatabase mDB = AppDatabase.getDatabase( this.getApplication() );
    mDataDao = mDB.dataDao();

    mExecutor = Executors.newSingleThreadExecutor();

}

...

private void receiveLocation( LocationResult locationResult ) {

    ...
    mExecutor.execute( () -> mDataDao.insertData( new eData( ... ) ) );

}

DataDao.java

@Dao
public interface DataDao {

    @Query( "SELECT * FROM eData" )
    LiveData<List<eData>> getAllData();

    @Insert
    long insertData( eData data );
}

AppDatabase.java

@Database(entities = { eData.class }, version = 1 )
public abstract class AppDatabase extends RoomDatabase {

    public abstract DataDao dataDao();

    private static AppDatabase INSTANCE;

    public static AppDatabase getDatabase( final Context context ) {
        if ( INSTANCE == null ) {
            synchronized ( AppDatabase.class ) {
                if ( INSTANCE == null ) {
                    INSTANCE = Room.databaseBuilder( context.getApplicationContext(),
                            AppDatabase.class, "locationapp" )
                                       .build();
                }
            }
        }
        return INSTANCE;
    }

The Repository and Database are Singletons. But somewhow the LiveData observed in my activity does not update when inserting entities in the service, which it does insert into the database, as when I restart the app, the count goes up.

Flecibel
  • 166
  • 2
  • 11
  • Your Service should be talking to the DAO directly (or a repository, whichever you use), and should have no ViewModel. Also, your DAO declaration is missing from this question, so we can't know what type of integration you use with Room DAO. – EpicPandaForce Aug 14 '19 at 13:17
  • I've added the declaration, and tested talking to it directly. LiveData in Activity still does not update the row count. – Flecibel Aug 14 '19 at 13:38
  • Hmm, are you sure the insert succeeds? – EpicPandaForce Aug 14 '19 at 13:47
  • 1
    Yes, both by viewing the database and by restarting the app/activity, the rowcount goes up to previous max. Just doesn't update while service is running and inserting.... – Flecibel Aug 14 '19 at 13:51
  • 1
    @Flecibel have you solved the problem. I'm experiencing something similar – rial Aug 03 '20 at 03:53
  • 1
    @rial See this answer: https://stackoverflow.com/a/44958478/7987898 Make sure you use the same DAO instance both for inserting and listening for updates. The service must use the same instance as the view model. –  Mar 08 '21 at 22:15
  • @dancesWithCodes I figured something like that. the db instance was correct since the data was written, just not listened to. Thanks for the link! – Flecibel Mar 11 '21 at 07:34

1 Answers1

0

Ended up not using room in the service at all. One, I didn't know whether it would be faster, and two, it uses less memory if I just stick with the activity and only create ViewModel and ExecutorService once.

Flecibel
  • 166
  • 2
  • 11