diff --git a/app/build.gradle b/app/build.gradle index f4619e045..6ffbd16b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,7 +83,7 @@ ext { icepickVersion = '3.2.0' checkstyleVersion = '8.32' stethoVersion = '1.5.1' - leakCanaryVersion = '1.5.4' + leakCanaryVersion = '2.2' exoPlayerVersion = '2.11.4' androidxLifecycleVersion = '2.2.0' androidxRoomVersion = '2.2.5' @@ -150,7 +150,7 @@ dependencies { debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}" debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}" - releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}" + implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}" debugImplementation "androidx.multidex:multidex:2.0.1" diff --git a/app/src/debug/java/org/schabi/newpipe/DebugApp.java b/app/src/debug/java/org/schabi/newpipe/DebugApp.java deleted file mode 100644 index 6bcf71035..000000000 --- a/app/src/debug/java/org/schabi/newpipe/DebugApp.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.schabi.newpipe; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import androidx.annotation.NonNull; -import androidx.multidex.MultiDex; - -import com.facebook.stetho.Stetho; -import com.facebook.stetho.okhttp3.StethoInterceptor; -import com.squareup.leakcanary.AndroidHeapDumper; -import com.squareup.leakcanary.DefaultLeakDirectoryProvider; -import com.squareup.leakcanary.HeapDumper; -import com.squareup.leakcanary.LeakCanary; -import com.squareup.leakcanary.LeakDirectoryProvider; -import com.squareup.leakcanary.RefWatcher; - -import org.schabi.newpipe.extractor.downloader.Downloader; - -import java.io.File; -import java.util.concurrent.TimeUnit; - -import okhttp3.OkHttpClient; - -public class DebugApp extends App { - private static final String TAG = DebugApp.class.toString(); - - @Override - protected void attachBaseContext(final Context base) { - super.attachBaseContext(base); - MultiDex.install(this); - } - - @Override - public void onCreate() { - super.onCreate(); - initStetho(); - } - - @Override - protected Downloader getDownloader() { - DownloaderImpl downloader = DownloaderImpl.init(new OkHttpClient.Builder() - .addNetworkInterceptor(new StethoInterceptor())); - setCookiesToDownloader(downloader); - return downloader; - } - - private void initStetho() { - // Create an InitializerBuilder - Stetho.InitializerBuilder initializerBuilder = - Stetho.newInitializerBuilder(this); - - // Enable Chrome DevTools - initializerBuilder.enableWebKitInspector( - Stetho.defaultInspectorModulesProvider(this) - ); - - // Enable command line interface - initializerBuilder.enableDumpapp( - Stetho.defaultDumperPluginsProvider(getApplicationContext()) - ); - - // Use the InitializerBuilder to generate an Initializer - Stetho.Initializer initializer = initializerBuilder.build(); - - // Initialize Stetho with the Initializer - Stetho.initialize(initializer); - } - - @Override - protected boolean isDisposedRxExceptionsReported() { - return PreferenceManager.getDefaultSharedPreferences(this) - .getBoolean(getString(R.string.allow_disposed_exceptions_key), false); - } - - @Override - protected RefWatcher installLeakCanary() { - return LeakCanary.refWatcher(this) - .heapDumper(new ToggleableHeapDumper(this)) - // give each object 10 seconds to be gc'ed, before leak canary gets nosy on it - .watchDelay(10, TimeUnit.SECONDS) - .buildAndInstall(); - } - - public static class ToggleableHeapDumper implements HeapDumper { - private final HeapDumper dumper; - private final SharedPreferences preferences; - private final String dumpingAllowanceKey; - - ToggleableHeapDumper(@NonNull final Context context) { - LeakDirectoryProvider leakDirectoryProvider = new DefaultLeakDirectoryProvider(context); - this.dumper = new AndroidHeapDumper(context, leakDirectoryProvider); - this.preferences = PreferenceManager.getDefaultSharedPreferences(context); - this.dumpingAllowanceKey = context.getString(R.string.allow_heap_dumping_key); - } - - private boolean isDumpingAllowed() { - return preferences.getBoolean(dumpingAllowanceKey, false); - } - - @Override - public File dumpHeap() { - return isDumpingAllowed() ? dumper.dumpHeap() : HeapDumper.RETRY_LATER; - } - } -} diff --git a/app/src/debug/java/org/schabi/newpipe/DebugApp.kt b/app/src/debug/java/org/schabi/newpipe/DebugApp.kt new file mode 100644 index 000000000..5cfde80b8 --- /dev/null +++ b/app/src/debug/java/org/schabi/newpipe/DebugApp.kt @@ -0,0 +1,59 @@ +package org.schabi.newpipe + +import android.content.Context +import androidx.multidex.MultiDex +import androidx.preference.PreferenceManager +import com.facebook.stetho.Stetho +import com.facebook.stetho.okhttp3.StethoInterceptor +import leakcanary.AppWatcher +import leakcanary.LeakCanary +import okhttp3.OkHttpClient +import org.schabi.newpipe.extractor.downloader.Downloader + +class DebugApp : App() { + override fun attachBaseContext(base: Context) { + super.attachBaseContext(base) + MultiDex.install(this) + } + + override fun onCreate() { + super.onCreate() + initStetho() + + // Give each object 10 seconds to be GC'ed, before LeakCanary gets nosy on it + AppWatcher.config = AppWatcher.config.copy(watchDurationMillis = 10000) + LeakCanary.config = LeakCanary.config.copy(dumpHeap = PreferenceManager + .getDefaultSharedPreferences(this).getBoolean(getString( + R.string.allow_heap_dumping_key), false)) + } + + override fun getDownloader(): Downloader { + val downloader = DownloaderImpl.init(OkHttpClient.Builder() + .addNetworkInterceptor(StethoInterceptor())) + setCookiesToDownloader(downloader) + return downloader + } + + private fun initStetho() { + // Create an InitializerBuilder + val initializerBuilder = Stetho.newInitializerBuilder(this) + + // Enable Chrome DevTools + initializerBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this)) + + // Enable command line interface + initializerBuilder.enableDumpapp( + Stetho.defaultDumperPluginsProvider(applicationContext)) + + // Use the InitializerBuilder to generate an Initializer + val initializer = initializerBuilder.build() + + // Initialize Stetho with the Initializer + Stetho.initialize(initializer) + } + + override fun isDisposedRxExceptionsReported(): Boolean { + return PreferenceManager.getDefaultSharedPreferences(this) + .getBoolean(getString(R.string.allow_disposed_exceptions_key), false) + } +} diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 8a4ed0607..02c816be9 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -9,14 +9,11 @@ import android.content.SharedPreferences; import android.os.Build; import android.util.Log; -import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; -import com.squareup.leakcanary.LeakCanary; -import com.squareup.leakcanary.RefWatcher; import org.acra.ACRA; import org.acra.config.ACRAConfiguration; @@ -72,13 +69,6 @@ public class App extends Application { private static final Class[] REPORT_SENDER_FACTORY_CLASSES = new Class[]{AcraReportSenderFactory.class}; private static App app; - private RefWatcher refWatcher; - - @Nullable - public static RefWatcher getRefWatcher(final Context context) { - final App application = (App) context.getApplicationContext(); - return application.refWatcher; - } public static App getApp() { return app; @@ -95,13 +85,6 @@ public class App extends Application { public void onCreate() { super.onCreate(); - if (LeakCanary.isInAnalyzerProcess(this)) { - // This process is dedicated to LeakCanary for heap analysis. - // You should not init your app in this process. - return; - } - refWatcher = installLeakCanary(); - app = this; // Initialize settings first because others inits can use its values @@ -280,10 +263,6 @@ public class App extends Application { appUpdateNotificationManager.createNotificationChannel(appUpdateChannel); } - protected RefWatcher installLeakCanary() { - return RefWatcher.DISABLED; - } - protected boolean isDisposedRxExceptionsReported() { return false; } diff --git a/app/src/main/java/org/schabi/newpipe/BaseFragment.java b/app/src/main/java/org/schabi/newpipe/BaseFragment.java index 9a86fd5ad..54513a0af 100644 --- a/app/src/main/java/org/schabi/newpipe/BaseFragment.java +++ b/app/src/main/java/org/schabi/newpipe/BaseFragment.java @@ -11,10 +11,10 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import com.nostra13.universalimageloader.core.ImageLoader; -import com.squareup.leakcanary.RefWatcher; import icepick.Icepick; import icepick.State; +import leakcanary.AppWatcher; public abstract class BaseFragment extends Fragment { public static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance(); @@ -78,16 +78,14 @@ public abstract class BaseFragment extends Fragment { Icepick.saveInstanceState(this, outState); } - protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { } + protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { + } @Override public void onDestroy() { super.onDestroy(); - RefWatcher refWatcher = App.getRefWatcher(getActivity()); - if (refWatcher != null) { - refWatcher.watch(this); - } + AppWatcher.INSTANCE.getObjectWatcher().watch(this); } @Override @@ -100,9 +98,11 @@ public abstract class BaseFragment extends Fragment { // Init //////////////////////////////////////////////////////////////////////////*/ - protected void initViews(final View rootView, final Bundle savedInstanceState) { } + protected void initViews(final View rootView, final Bundle savedInstanceState) { + } - protected void initListeners() { } + protected void initListeners() { + } /*////////////////////////////////////////////////////////////////////////// // Utils