Skip to content

Commit

Permalink
Improve (un)registering FragmentLifecycleCallbacks
Browse files Browse the repository at this point in the history
to avoid adding it multiple times and ensure proper cleanup
  • Loading branch information
devlearner committed Dec 2, 2022
1 parent 284587d commit 6fd2c06
Showing 1 changed file with 27 additions and 20 deletions.
47 changes: 27 additions & 20 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.math.MathUtils;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;
Expand Down Expand Up @@ -113,6 +114,7 @@ public class RouterActivity extends AppCompatActivity {
private boolean selectionIsDownload = false;
private boolean selectionIsAddToPlaylist = false;
private AlertDialog alertDialogChoice = null;
private FragmentManager.FragmentLifecycleCallbacks dismissListener = null;

@Override
protected void onCreate(final Bundle savedInstanceState) {
Expand Down Expand Up @@ -142,6 +144,27 @@ protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState);

// FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates
// We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments
// but those callbacks won't survive a config change
// Try an alternate approach to hook into FragmentManager instead, to that effect
// (ref: https://stackoverflow.com/a/44028453)
final FragmentManager fm = getSupportFragmentManager();
if (dismissListener == null) {
dismissListener = new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentDestroyed(@NonNull final FragmentManager fm,
@NonNull final Fragment f) {
super.onFragmentDestroyed(fm, f);
if (f instanceof DialogFragment && fm.getFragments().isEmpty()) {
// No more DialogFragments, we're done
finish();
}
}
};
}
fm.registerFragmentLifecycleCallbacks(dismissListener, false);

if (TextUtils.isEmpty(currentUrl)) {
currentUrl = getUrl(getIntent());

Expand Down Expand Up @@ -171,29 +194,10 @@ protected void onSaveInstanceState(@NonNull final Bundle outState) {
protected void onStart() {
super.onStart();

// FragmentManager will take care to recreate DialogFragments when screen rotates
// currently that's namely PlaylistDialog or DownloadDialog
// We used to .setOnDismissListener(dialog ->finish()); when creating those Dialogs
// but those callbacks won't survive a config change
// Try an alternate approach to hook into FragmentManager instead, to that effect
// (courtesy of https://stackoverflow.com/a/44028453)
final FragmentManager fm = getSupportFragmentManager();
fm.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentViewDestroyed(@NonNull final FragmentManager fm,
@NonNull final Fragment f) {
super.onFragmentViewDestroyed(fm, f);
if (fm.getFragments().isEmpty()) {
// No more Dialog, we're done
finish();
}
}
}, false);

// Don't overlap the DialogFragment after rotating the screen
// If there's no DialogFragment, we're either starting afresh
// or we didn't make it to PlaylistDialog or DownloadDialog before the orientation change
if (fm.getFragments().isEmpty()) {
if (getSupportFragmentManager().getFragments().isEmpty()) {
// Start over from scratch
handleUrl(currentUrl);
}
Expand All @@ -203,6 +207,9 @@ public void onFragmentViewDestroyed(@NonNull final FragmentManager fm,
protected void onDestroy() {
super.onDestroy();

if (dismissListener != null) {
getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener);
}
disposables.clear();
}

Expand Down

0 comments on commit 6fd2c06

Please sign in to comment.