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...
android broadcastreceiver android-room android-livedata
add a comment |
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...
android broadcastreceiver android-room android-livedata
add a comment |
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...
android broadcastreceiver android-room android-livedata
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
android broadcastreceiver android-room android-livedata
edited Nov 8 at 8:55
asked Nov 7 at 15:32
MatBB
62
62
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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