Showing DialogFragment while Application is on background

421 Views Asked by At

Case is after I got a response from my async task, I want to show a DialogFragment. But if user put the application to background while the app still waiting for the response, on the moment the response came and .show DialogFragment it will crashed.

I've done immediate fix by try catching the .show, but the DialogFragment won't show after user return to the app.

Is there a clean way to let the application keep on showing DialogFragment while on background or on the next onResume ?

The only way I found while googling is using an ActivityDialog, but it will require much effort.

Edit : Eh I actually able to show it now with commitStateLoss ._. from customErrorDialog.show(((FragmentActivity) context).getSupportFragmentManager(), "TAG"); to ((FragmentActivity)context).getSupportFragmentManager().beginTransaction().add(customErrorDialog, "TAG").commitAllowingStateLoss();

idk if this is dangerous for some specific case though

1

There are 1 best solutions below

0
hasan.z On

You should use lifecycle-aware components to receive response.

  1. For android-java projects simply use livedata. Base on the document:

LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state. LiveData considers an observer, which is represented by the Observer class, to be in an active state if its lifecycle is in the STARTED or RESUMED state.

  1. For android-kotlin projects, you have more options than java. You can still use livedata like Java. Other options are StateFlow, which is part of the flow and coroutines. Collecting them with repeatOnLifecycle. Base on document:

    public class NameActivity extends AppCompatActivity {
    
    private NameViewModel model;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Other code to setup the activity...
    
        // Get the ViewModel.
        model = new ViewModelProvider(this).get(NameViewModel.class);
    
        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                nameTextView.setText(newName);
            }
        };
    
        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.getCurrentName().observe(this, nameObserver);
    }
    }
    

StateFlow and SharedFlow are Flow APIs that enable flows to optimally emit state updates and emit values to multiple consumers.

You can find this behavior in other observable classes like LiveData

class LatestNewsActivity : AppCompatActivity() {
private val latestNewsViewModel = // getViewModel()

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    // Start a coroutine in the lifecycle scope
    lifecycleScope.launch {
        // repeatOnLifecycle launches the block in a new coroutine every time the
        // lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            // Trigger the flow and start listening for values.
            // Note that this happens when lifecycle is STARTED and stops
            // collecting when the lifecycle is STOPPED
            latestNewsViewModel.uiState.collect { uiState ->
                // New value received
                when (uiState) {
                    is LatestNewsUiState.Success -> showFavoriteNews(uiState.news)
                    is LatestNewsUiState.Error -> showError(uiState.exception)
                }
            }
        }
    }
}