Is my leakcanary working? How to know?

4.6k views Asked by At

I believe to have successfully installed LeakCanary.

I added the debug, release, and test dependencies to the build.gradle file.

I added the necessary files to my Application Class. Imported as necessary. Confirmed the application class is properly added to manifest. Does my application class need to be explicitly called?

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"

I run my app on the emulator and don't see anything different. I monitor the Android Monitor and don't see any difference. How do I know if it's all working? I've shared my Application class.

import android.app.Application;
import android.content.res.Configuration;
import com.squareup.leakcanary.LeakCanary;

public class MyApplication extends Application {

@Override
public void onCreate() {
    super.onCreate();

    if (LeakCanary.isInAnalyzerProcess(this)) {
        return;
    }
    LeakCanary.install(this);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

@Override
public void onLowMemory() {
    super.onLowMemory();
}

}

2

There are 2 answers

4
CommonsWare On BEST ANSWER

Does my application class need to be explicitly called?

No.

How do I know if it's all working?

Leak something intentionally. For example, assign your launcher activity instance to a static field.

3
Paul Spiesberger On

First, check if you are attached to a debugger? LeakCanary ignores leak detection when debugging to avoid false positives.

Second, Add the LeakCanary via Gradle and then do the following:

class App : Application() {

    companion object {
        @JvmStatic
        fun getRefWatcher(context: Context): RefWatcher {
            val applicationContext = context.applicationContext as App
            return applicationContext.refWatcher
        }
    }

    private lateinit var refWatcher: RefWatcher

    override fun 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 = LeakCanary.install(this)
    }
}

In your Fragment (best you use a BaseFragment)

override fun onDestroy() {

   if (BuildConfig.DEBUG) {
      activity?.let {
         App.getRefWatcher(it).watch(this)
      }
      super.onDestroy()
}

Then in one of your Sub-Activities with a Fragment do:

class MemLeakFragment : BaseFragment() {

    companion object {
        @JvmStatic
        lateinit var memleak: Activity
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        activity?.let {
            memleak = it
        }
    }
}

Open the Activity with the memleak Fragment and close it with a back press. Wait a bit and LeakCanary will report the memory leak, this can take a while...