Repository: square/leakcanary
Issue: Leak analysis fails 100% of the time

### Description
Heap analysis fails whenever theres a leak in my project.

### Steps to Reproduce
[**.hprof file**](https://drive.google.com/file/d/1-bur0zjX7bZoxdk4xiRhb32-lCmKaNKT/view?usp=sharing)

````
kotlin.KotlinNullPointerException
	at shark.AndroidObjectInspectors$VIEW_ROOT_IMPL$inspect$1.invoke(AndroidObjectInspectors.kt:657)
	at shark.AndroidObjectInspectors$VIEW_ROOT_IMPL$inspect$1.invoke(AndroidObjectInspectors.kt:615)
	at shark.ObjectReporter.whenInstanceOf(ObjectReporter.kt:61)
	at shark.AndroidObjectInspectors$VIEW_ROOT_IMPL.inspect(AndroidObjectInspectors.kt:638)
	at shark.HeapAnalyzer.inspectObjects(HeapAnalyzer.kt:424)
	at shark.HeapAnalyzer.findLeaks(HeapAnalyzer.kt:204)
	at shark.HeapAnalyzer.analyzeGraph(HeapAnalyzer.kt:175)
	at shark.HeapAnalyzer.analyze(HeapAnalyzer.kt:101)
	at leakcanary.internal.HeapAnalyzerService.analyzeHeap(HeapAnalyzerService.kt:87)
	at leakcanary.internal.HeapAnalyzerService.onHandleIntentInForeground(HeapAnalyzerService.kt:61)
	at leakcanary.internal.ForegroundService.onHandleIntent(ForegroundService.kt:55)
	at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:201)
	at android.os.Looper.loop(Looper.java:288)
	at android.os.HandlerThread.run(HandlerThread.java:67)

Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: Google
LeakCanary version: 2.7
Analysis duration: 6754 ms
Heap dump file path: /storage/emulated/0/Download/leakcanary-x/2021-11-05_12-50-41_011.hprof
Heap dump timestamp: 1636116662893
````

### Version Information

* LeakCanary version: 2.7
* Android OS version: 31
* Gradle version: 7.1.0-alpha03

### Additional Information
I do use jetpack compose in my project, not sure if that makes a difference.

Changed files:
shark-android/src/main/java/shark/AndroidObjectInspectors.kt

diff --git a/shark-android/src/main/java/shark/AndroidObjectInspectors.kt b/shark-android/src/main/java/shark/AndroidObjectInspectors.kt
index 99afbcebe..59fcdf373 100644
--- a/shark-android/src/main/java/shark/AndroidObjectInspectors.kt
+++ b/shark-android/src/main/java/shark/AndroidObjectInspectors.kt
@@ -653,9 +653,14 @@ enum class AndroidObjectInspectors : ObjectInspector {
         }
         val mWindowAttributes =
           instance["android.view.ViewRootImpl", "mWindowAttributes"]!!.valueAsInstance!!
-        val mTitle =
-          mWindowAttributes["android.view.WindowManager\\$LayoutParams", "mTitle"]!!.valueAsInstance!!.readAsJavaString()!!
-        labels += "mWindowAttributes.mTitle = \\"$mTitle\\""
+        val mTitleField = mWindowAttributes["android.view.WindowManager\\$LayoutParams", "mTitle"]!!
+        if (mTitleField.value.isNonNullReference) {
+          val mTitle =
+            mTitleField.valueAsInstance!!.readAsJavaString()!!
+          labels += "mWindowAttributes.mTitle = \\"$mTitle\\""
+        } else {
+          labels += "mWindowAttributes.mTitle is null"
+        }
 
         val type =
           mWindowAttributes["android.view.WindowManager\\$LayoutParams", "type"]!!.value.asInt!!
@@ -951,4 +956,4 @@ You can run LeakCanary on obfuscated builds by following the instructions at
 https://square.github.io/leakcanary/recipes/#using-leakcanary-with-obfuscated-apps
       """
   )
-}
\\ No newline at end of file
+}