1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-01-24 07:56:57 +00:00

Initial commit for better handling of background crashes

This commit is contained in:
Thompson3142 2024-12-03 00:51:15 +01:00
parent 70748fa0bc
commit 402f0b15aa
4 changed files with 44 additions and 1 deletions

View File

@ -227,6 +227,7 @@ dependencies {
implementation 'androidx.fragment:fragment-ktx:1.6.2' implementation 'androidx.fragment:fragment-ktx:1.6.2'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-process:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'androidx.media:media:1.7.0' implementation 'androidx.media:media:1.7.0'
implementation 'androidx.preference:preference:1.2.1' implementation 'androidx.preference:preference:1.2.1'

View File

@ -0,0 +1,32 @@
package org.schabi.newpipe.error
import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import java.util.concurrent.atomic.AtomicLong
object AppLifecycleObserver : DefaultLifecycleObserver {
private var isInBackground = false
private val lastBackgroundTimestamp = AtomicLong(0)
private var TAG = javaClass.simpleName
override fun onStart(owner: LifecycleOwner) {
isInBackground = false
Log.d(TAG, "App moved to foreground")
}
override fun onStop(owner: LifecycleOwner) {
isInBackground = true
lastBackgroundTimestamp.set(System.currentTimeMillis())
Log.d(TAG, "App moved to background")
}
fun isAppInBackground(): Boolean = isInBackground
/**
* @return the elapsed time since the app moved to the background or 0 if it is in foreground
*/
fun getTimeSinceLastBackground(): Long {
return if (isInBackground) System.currentTimeMillis() - lastBackgroundTimestamp.get() else 0
}
}

View File

@ -35,13 +35,20 @@ class ErrorUtil {
* activity (since the workflow would be interrupted anyway in that case). So never use this * activity (since the workflow would be interrupted anyway in that case). So never use this
* for background services. * for background services.
* *
* If this method is called while the app has been in the background for more than
* 10 seconds it will not start an error activity and instead create a notification
*
* @param context the context to use to start the new activity * @param context the context to use to start the new activity
* @param errorInfo the error info to be reported * @param errorInfo the error info to be reported
*/ */
@JvmStatic @JvmStatic
fun openActivity(context: Context, errorInfo: ErrorInfo) { fun openActivity(context: Context, errorInfo: ErrorInfo) {
if (AppLifecycleObserver.getTimeSinceLastBackground() > 10000) {
createNotification(context, errorInfo)
} else {
context.startActivity(getErrorActivityIntent(context, errorInfo)) context.startActivity(getErrorActivityIntent(context, errorInfo))
} }
}
/** /**
* Show a bottom snackbar to the user, with a report button that opens the error activity. * Show a bottom snackbar to the user, with a report button that opens the error activity.

View File

@ -28,6 +28,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapterMenuWorkaround; import androidx.fragment.app.FragmentStatePagerAdapterMenuWorkaround;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
@ -36,6 +37,7 @@ import com.google.android.material.tabs.TabLayout;
import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.FragmentMainBinding; import org.schabi.newpipe.databinding.FragmentMainBinding;
import org.schabi.newpipe.error.AppLifecycleObserver;
import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
@ -71,6 +73,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
@Override @Override
public void onCreate(final Bundle savedInstanceState) { public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ProcessLifecycleOwner.get().getLifecycle().addObserver(AppLifecycleObserver.INSTANCE);
setHasOptionsMenu(true); setHasOptionsMenu(true);
tabsManager = TabsManager.getManager(activity); tabsManager = TabsManager.getManager(activity);
tabsManager.setSavedTabsListener(() -> { tabsManager.setSavedTabsListener(() -> {