Observer onChanged() does not send the latest value set











up vote
1
down vote

favorite












I am using LiveData and Room Database in a BroadcastReceiver.



The main idea is to perform a single query on the database (insert, remove, get) and forward the updated value to the caller.



Thanks to an Observer listening to the LiveData object, I am able to get the updated value. Then the value is forwarded to the caller via setResultData().



This is my BroadcastReceiver:



public class WordReceiver extends BroadcastReceiver {
...

private List<Sring> mWordList;
private WordItemViewModel mWordItemViewModel;
private Observer<List<String>> mObserver;
private boolean mActionPerformed = false;

...

@Override
public void onReceive(final Context context, final Intent intent) {
final PendingResult result = goAsync();

new Thread() {
public void run() {
manageActions(context, intent, result);
}
}.start()
}

...

private void manageActions(Context context, Intent intent, PendingResult result) {
String action = intent.getAction();
if (action == null) {
return;
}
switch (action) {
case WordReceiver.ACTION_ADD_WORD:
initVariables(context, result);
mActionPerformed = true;
mWordItemViewModel.insert(intent.getStringExtra(WordReceiver.EXTRA_WORD);
break;
case WordReceiver.ACTION_REMOVE_WORD:
initVariables(context, result);
mActionPerformed = true;
mWordItemViewModel.delete(intent.getStringExtra(WordReceiver.EXTRA_WORD);
break;
case WordReceiver.ACTION_GET_WORDS:
// mActionPerformed is set to true because there is no action to perform
mActionPerformed = true;
initVariables(context, result);
break;
default:
result.abortBroadcast();
break;
}
}
}


The Observer and the AndroidViewModel are initialized this way:



private void initVariables(final Context context, final PendingResult result) {
mWordItemViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance((Application) context.getApplicationContext()).create(WordItemViewModel.class);

mObserver = new Observer<List<String>>() {
@Override
public void onChanged(@Nullable final List<String> wordList) {
mWordList = wordList;

if (mActionPerformed) {
mWordItemViewModel.getAllWordItems().removeObserver(this);

if (mWordList != null) {
String wordListText = TextUtils.join(",", mWordList);
result.setResultData(wordListText);
}
result.finish();
}
}
};

mWordItemViewModel.getAllWordItems().observeForever(mObserver);
}


This works, but not always !



Sometimes the wordList parameter in onChanged() takes into account the added/removed Word, sometimes not.



According to https://developer.android.com/reference/android/arch/lifecycle/LiveData#getvalue




Returns the current value. Note that calling this method on a
background thread does not guarantee that the latest value set will be
received.




I am not using getvalue(), but I wonder if the onChanged() method may have the same behavior.



Thanks a lot...










share|improve this question




























    up vote
    1
    down vote

    favorite












    I am using LiveData and Room Database in a BroadcastReceiver.



    The main idea is to perform a single query on the database (insert, remove, get) and forward the updated value to the caller.



    Thanks to an Observer listening to the LiveData object, I am able to get the updated value. Then the value is forwarded to the caller via setResultData().



    This is my BroadcastReceiver:



    public class WordReceiver extends BroadcastReceiver {
    ...

    private List<Sring> mWordList;
    private WordItemViewModel mWordItemViewModel;
    private Observer<List<String>> mObserver;
    private boolean mActionPerformed = false;

    ...

    @Override
    public void onReceive(final Context context, final Intent intent) {
    final PendingResult result = goAsync();

    new Thread() {
    public void run() {
    manageActions(context, intent, result);
    }
    }.start()
    }

    ...

    private void manageActions(Context context, Intent intent, PendingResult result) {
    String action = intent.getAction();
    if (action == null) {
    return;
    }
    switch (action) {
    case WordReceiver.ACTION_ADD_WORD:
    initVariables(context, result);
    mActionPerformed = true;
    mWordItemViewModel.insert(intent.getStringExtra(WordReceiver.EXTRA_WORD);
    break;
    case WordReceiver.ACTION_REMOVE_WORD:
    initVariables(context, result);
    mActionPerformed = true;
    mWordItemViewModel.delete(intent.getStringExtra(WordReceiver.EXTRA_WORD);
    break;
    case WordReceiver.ACTION_GET_WORDS:
    // mActionPerformed is set to true because there is no action to perform
    mActionPerformed = true;
    initVariables(context, result);
    break;
    default:
    result.abortBroadcast();
    break;
    }
    }
    }


    The Observer and the AndroidViewModel are initialized this way:



    private void initVariables(final Context context, final PendingResult result) {
    mWordItemViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance((Application) context.getApplicationContext()).create(WordItemViewModel.class);

    mObserver = new Observer<List<String>>() {
    @Override
    public void onChanged(@Nullable final List<String> wordList) {
    mWordList = wordList;

    if (mActionPerformed) {
    mWordItemViewModel.getAllWordItems().removeObserver(this);

    if (mWordList != null) {
    String wordListText = TextUtils.join(",", mWordList);
    result.setResultData(wordListText);
    }
    result.finish();
    }
    }
    };

    mWordItemViewModel.getAllWordItems().observeForever(mObserver);
    }


    This works, but not always !



    Sometimes the wordList parameter in onChanged() takes into account the added/removed Word, sometimes not.



    According to https://developer.android.com/reference/android/arch/lifecycle/LiveData#getvalue




    Returns the current value. Note that calling this method on a
    background thread does not guarantee that the latest value set will be
    received.




    I am not using getvalue(), but I wonder if the onChanged() method may have the same behavior.



    Thanks a lot...










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am using LiveData and Room Database in a BroadcastReceiver.



      The main idea is to perform a single query on the database (insert, remove, get) and forward the updated value to the caller.



      Thanks to an Observer listening to the LiveData object, I am able to get the updated value. Then the value is forwarded to the caller via setResultData().



      This is my BroadcastReceiver:



      public class WordReceiver extends BroadcastReceiver {
      ...

      private List<Sring> mWordList;
      private WordItemViewModel mWordItemViewModel;
      private Observer<List<String>> mObserver;
      private boolean mActionPerformed = false;

      ...

      @Override
      public void onReceive(final Context context, final Intent intent) {
      final PendingResult result = goAsync();

      new Thread() {
      public void run() {
      manageActions(context, intent, result);
      }
      }.start()
      }

      ...

      private void manageActions(Context context, Intent intent, PendingResult result) {
      String action = intent.getAction();
      if (action == null) {
      return;
      }
      switch (action) {
      case WordReceiver.ACTION_ADD_WORD:
      initVariables(context, result);
      mActionPerformed = true;
      mWordItemViewModel.insert(intent.getStringExtra(WordReceiver.EXTRA_WORD);
      break;
      case WordReceiver.ACTION_REMOVE_WORD:
      initVariables(context, result);
      mActionPerformed = true;
      mWordItemViewModel.delete(intent.getStringExtra(WordReceiver.EXTRA_WORD);
      break;
      case WordReceiver.ACTION_GET_WORDS:
      // mActionPerformed is set to true because there is no action to perform
      mActionPerformed = true;
      initVariables(context, result);
      break;
      default:
      result.abortBroadcast();
      break;
      }
      }
      }


      The Observer and the AndroidViewModel are initialized this way:



      private void initVariables(final Context context, final PendingResult result) {
      mWordItemViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance((Application) context.getApplicationContext()).create(WordItemViewModel.class);

      mObserver = new Observer<List<String>>() {
      @Override
      public void onChanged(@Nullable final List<String> wordList) {
      mWordList = wordList;

      if (mActionPerformed) {
      mWordItemViewModel.getAllWordItems().removeObserver(this);

      if (mWordList != null) {
      String wordListText = TextUtils.join(",", mWordList);
      result.setResultData(wordListText);
      }
      result.finish();
      }
      }
      };

      mWordItemViewModel.getAllWordItems().observeForever(mObserver);
      }


      This works, but not always !



      Sometimes the wordList parameter in onChanged() takes into account the added/removed Word, sometimes not.



      According to https://developer.android.com/reference/android/arch/lifecycle/LiveData#getvalue




      Returns the current value. Note that calling this method on a
      background thread does not guarantee that the latest value set will be
      received.




      I am not using getvalue(), but I wonder if the onChanged() method may have the same behavior.



      Thanks a lot...










      share|improve this question















      I am using LiveData and Room Database in a BroadcastReceiver.



      The main idea is to perform a single query on the database (insert, remove, get) and forward the updated value to the caller.



      Thanks to an Observer listening to the LiveData object, I am able to get the updated value. Then the value is forwarded to the caller via setResultData().



      This is my BroadcastReceiver:



      public class WordReceiver extends BroadcastReceiver {
      ...

      private List<Sring> mWordList;
      private WordItemViewModel mWordItemViewModel;
      private Observer<List<String>> mObserver;
      private boolean mActionPerformed = false;

      ...

      @Override
      public void onReceive(final Context context, final Intent intent) {
      final PendingResult result = goAsync();

      new Thread() {
      public void run() {
      manageActions(context, intent, result);
      }
      }.start()
      }

      ...

      private void manageActions(Context context, Intent intent, PendingResult result) {
      String action = intent.getAction();
      if (action == null) {
      return;
      }
      switch (action) {
      case WordReceiver.ACTION_ADD_WORD:
      initVariables(context, result);
      mActionPerformed = true;
      mWordItemViewModel.insert(intent.getStringExtra(WordReceiver.EXTRA_WORD);
      break;
      case WordReceiver.ACTION_REMOVE_WORD:
      initVariables(context, result);
      mActionPerformed = true;
      mWordItemViewModel.delete(intent.getStringExtra(WordReceiver.EXTRA_WORD);
      break;
      case WordReceiver.ACTION_GET_WORDS:
      // mActionPerformed is set to true because there is no action to perform
      mActionPerformed = true;
      initVariables(context, result);
      break;
      default:
      result.abortBroadcast();
      break;
      }
      }
      }


      The Observer and the AndroidViewModel are initialized this way:



      private void initVariables(final Context context, final PendingResult result) {
      mWordItemViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance((Application) context.getApplicationContext()).create(WordItemViewModel.class);

      mObserver = new Observer<List<String>>() {
      @Override
      public void onChanged(@Nullable final List<String> wordList) {
      mWordList = wordList;

      if (mActionPerformed) {
      mWordItemViewModel.getAllWordItems().removeObserver(this);

      if (mWordList != null) {
      String wordListText = TextUtils.join(",", mWordList);
      result.setResultData(wordListText);
      }
      result.finish();
      }
      }
      };

      mWordItemViewModel.getAllWordItems().observeForever(mObserver);
      }


      This works, but not always !



      Sometimes the wordList parameter in onChanged() takes into account the added/removed Word, sometimes not.



      According to https://developer.android.com/reference/android/arch/lifecycle/LiveData#getvalue




      Returns the current value. Note that calling this method on a
      background thread does not guarantee that the latest value set will be
      received.




      I am not using getvalue(), but I wonder if the onChanged() method may have the same behavior.



      Thanks a lot...







      android broadcastreceiver android-room android-livedata






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 8 at 8:55

























      asked Nov 7 at 15:32









      MatBB

      62




      62





























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53192645%2fobserver-onchanged-does-not-send-the-latest-value-set%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53192645%2fobserver-onchanged-does-not-send-the-latest-value-set%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()