I encountered a weird issue with Snackbars on android. I show error messages via an Snackbar + Retry-Action. When 'Retry' is clicked and the error is still here (e.g. no internet) I show the error again. This click on the action in the Snackbar automatically dismisses the currently shown one, and showing a new Snackbar while the old one still 'fades out' works as expected.
But sometimes (when I click 'Retry' ~30 times) a Snackbar doesn't show up at all after I press the button many times.
I can reproduce it with this simple code:
final View.OnClickListener retryListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
showSnackbar();
}
};
private void showSnackbar() {
Snackbar snackbar = Snackbar.make(root, "Error", BaseTransientBottomBar.LENGTH_INDEFINITE)
.setAction("Retry", retryListener)
//Callback only for debugging-purposes
.addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
@Override
public void onShown(Snackbar transientBottomBar) {
super.onShown(transientBottomBar);
Log.d(TAG, "onShown called");
}
});
snackbar.show();
Log.d(TAG, "show called");
}
When I take a look at logcat after the problem occurs with this code, the last line is show called
and the onShown
-callback wasn't called anymore.
Why would this happen? Should I report this as an issue? Any workarounds known?
Snackbars contain a single line of text directly related to the operation performed. They may contain a text action, but no icons. Toasts (Android only) are primarily used for system messaging. They also display at the bottom of the screen, but may not be swiped off-screen.
The variable _isSnackbarActive to true when snackBar is displayed and set it to false when it is closed. In your onPressed event, just check the status of the snackbar and decide if new snackbar is to be shown or not.
When you click on the “Show Snackbar” button, a Snackbar appears at the bottom of the screen. An action could be set to Snackbar using Snackbar. setAction() method.
I haven't found a real reason why it happens nor a real solution to the problem, but I found a workaround which works for me:
private Snackbar currentlyShownSnackbar;
private void showSnackbar() {
Snackbar snackbar = Snackbar.make(...);
snackbar.show();
currentlyShownSnackbar = snackbar;
}
Simply by keeping a reference to the currently shown Snackbar, this problem doesn't happen anymore. I don't know why, maybe it is related to too early garbage-collection.
Code inspection will say that this variable is assigned but never used - this warning can be ignored.
I also added this in my Activity to prevent any possible memory leak:
public void onPause() {
super.onPause();
this.currentlyShownSnackbar = null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With