mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 00:20:32 +00:00
Utilize Lifecycle observer
I thought it would have required an extra dependency; apparently that doesn't seem to be the case...
This commit is contained in:
parent
61da167b4f
commit
40442f3f82
@ -36,6 +36,9 @@ import androidx.core.math.MathUtils;
|
|||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
||||||
@ -88,7 +91,6 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import icepick.Icepick;
|
import icepick.Icepick;
|
||||||
import icepick.State;
|
import icepick.State;
|
||||||
@ -213,6 +215,7 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
if (dismissListener != null) {
|
if (dismissListener != null) {
|
||||||
getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener);
|
getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
disposables.clear();
|
disposables.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,9 +702,20 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public static class PersistentFragment extends Fragment {
|
public static class PersistentFragment extends Fragment {
|
||||||
private WeakReference<AppCompatActivity> context;
|
private WeakReference<AppCompatActivity> context;
|
||||||
private boolean isPaused = true;
|
|
||||||
private final Vector<ResultRunnable> buffer = new Vector<>();
|
|
||||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||||
|
private int running = 0;
|
||||||
|
|
||||||
|
private synchronized void inFlight(final boolean started) {
|
||||||
|
if (started) {
|
||||||
|
running++;
|
||||||
|
} else {
|
||||||
|
running--;
|
||||||
|
if (running <= 0 && getActivityContext() != null) {
|
||||||
|
getActivityContext().getSupportFragmentManager()
|
||||||
|
.beginTransaction().remove(this).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface ResultRunnable {
|
public interface ResultRunnable {
|
||||||
void run(AppCompatActivity context);
|
void run(AppCompatActivity context);
|
||||||
@ -726,59 +740,44 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
disposables.clear();
|
disposables.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
isPaused = true;
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
isPaused = false;
|
|
||||||
playback();
|
|
||||||
super.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
private AppCompatActivity getActivityContext() {
|
private AppCompatActivity getActivityContext() {
|
||||||
return context == null ? null : context.get();
|
return context == null ? null : context.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean activityGone() {
|
||||||
|
return getActivityContext() == null || getActivityContext().isFinishing();
|
||||||
|
}
|
||||||
|
|
||||||
// guard against IllegalStateException in calling DialogFragment.show() whilst in background
|
// guard against IllegalStateException in calling DialogFragment.show() whilst in background
|
||||||
// (which could happen, say, when the user pressed the home button while waiting for
|
// (which could happen, say, when the user pressed the home button while waiting for
|
||||||
// the network request to return) when it internally calls FragmentTransaction.commit()
|
// the network request to return) when it internally calls FragmentTransaction.commit()
|
||||||
// after the FragmentManager has saved its states (isStateSaved() == true)
|
// after the FragmentManager has saved its states (isStateSaved() == true)
|
||||||
// (ref: https://stackoverflow.com/a/39813506)
|
// (ref: https://stackoverflow.com/a/39813506)
|
||||||
private void playback() {
|
|
||||||
if (activityGone()) {
|
|
||||||
done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buffer.size() == 0 || isPaused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (buffer.size() > 0) {
|
|
||||||
final ResultRunnable runnable = buffer.elementAt(0);
|
|
||||||
buffer.removeElementAt(0);
|
|
||||||
getActivityContext().runOnUiThread(() ->
|
|
||||||
// execute queued task with new context, in case activity has been recreated
|
|
||||||
runnable.run(getActivityContext())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
private boolean activityGone() {
|
|
||||||
return getActivityContext() == null || getActivityContext().isFinishing();
|
|
||||||
}
|
|
||||||
|
|
||||||
// a DefaultLifecycleObserver is probably a good candidate here, but for now
|
|
||||||
// let's stick with a vanilla approach to avoid pulling in an extra artifact just for this
|
|
||||||
private void runOnVisible(final ResultRunnable runnable) {
|
private void runOnVisible(final ResultRunnable runnable) {
|
||||||
if (activityGone()) {
|
if (activityGone()) {
|
||||||
done();
|
inFlight(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isPaused) {
|
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
|
||||||
buffer.add(runnable);
|
getActivityContext().runOnUiThread(() -> {
|
||||||
|
runnable.run(getActivityContext());
|
||||||
|
inFlight(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getLifecycle().addObserver(new DefaultLifecycleObserver() {
|
||||||
|
@Override
|
||||||
|
public void onResume(@NonNull final LifecycleOwner owner) {
|
||||||
|
getLifecycle().removeObserver(this);
|
||||||
|
if (activityGone()) {
|
||||||
|
inFlight(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getActivityContext().runOnUiThread(() -> {
|
||||||
|
runnable.run(getActivityContext());
|
||||||
|
inFlight(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
// this trick doesn't seem to work on Android 10+ (API 29)
|
// this trick doesn't seem to work on Android 10+ (API 29)
|
||||||
// which places restrictions on starting activities from the background
|
// which places restrictions on starting activities from the background
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
||||||
@ -788,23 +787,12 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
getActivityContext().runOnUiThread(() -> {
|
|
||||||
runnable.run(getActivityContext());
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void done() {
|
|
||||||
if (getActivityContext() != null) {
|
|
||||||
getActivityContext().getSupportFragmentManager()
|
|
||||||
.beginTransaction().remove(this).commit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
protected void openDownloadDialog(final int currentServiceId, final String currentUrl) {
|
private void openDownloadDialog(final int currentServiceId, final String currentUrl) {
|
||||||
|
inFlight(true);
|
||||||
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
|
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -820,6 +808,7 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) {
|
private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) {
|
||||||
|
inFlight(true);
|
||||||
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
|
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -870,7 +859,7 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
return persistFragment;
|
return persistFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void pleaseWait() {
|
private void pleaseWait() {
|
||||||
// Getting the stream info usually takes a moment
|
// Getting the stream info usually takes a moment
|
||||||
// Notifying the user here to ensure that no confusion arises
|
// Notifying the user here to ensure that no confusion arises
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
Loading…
Reference in New Issue
Block a user