Repository: square/leakcanary
File: leakcanary-android-core/src/main/java/leakcanary/DefaultOnHeapAnalyzedListener.kt (Kotlin)

Code before:
    if (InternalLeakCanary.formFactor == TV) {
      showToast()
      printIntentInfo()
    } else {
      showNotification(screenToShow, contentTitle)
    }
  }

  private fun showNotification(
    screenToShow: Screen,
    contentTitle: String
  ) {
    val pendingIntent = LeakActivity.createPendingIntent(
        application, arrayListOf(HeapDumpsScreen(), screenToShow)
    )

    val contentText = application.getString(R.string.leak_canary_notification_message)

    Notifications.showNotification(
        application, contentTitle, contentText, pendingIntent,
        R.id.leak_canary_notification_analysis_result,
        LEAKCANARY_RESULT
    )
  }

  /**
   * Android TV devices do not have notifications, therefore the only easy and non-invasive way
   * to communicate with user is via Toast messages. These are used just to grab user attention and
   * to direct them to Logcat where a much more detailed report will be printed.
   */
  private fun showToast() {
    // Post the Toast into main thread and wrap it with try-catch in case Toast crashes (it happens)
    handler.post {
      try {
        Toast.makeText(
            application,
            "Analysis complete, please check Logcat",
            Toast.LENGTH_LONG
        )
            .show()
      } catch (exception: Exception) {
        // Toasts are prone to crashing, ignore
      }
    }
  }

  /**
   * Android TV with API 26+ has a bug where launcher icon doesn't appear, so users won't know how
   * to launch LeakCanary Activity.
   * This method would print an adb command that launched LeakCanary into the logcat
   */

Review comment (bug):
What's this about? Toasts aren't prone to crashing, and if they were we should have specific code to handle those edge cases. The one crash that can happen is related to background / foreground, there are ways around it but catching will definitely do nothing as it's always crashing from a delayed message

Code after:
    val contentText = application.getString(R.string.leak_canary_notification_message)

    Notifications.showNotification(
        application, contentTitle, contentText, pendingIntent,
        R.id.leak_canary_notification_analysis_result,
        LEAKCANARY_MAX
    )
  }

  /**
   * Android TV devices do not have notifications, therefore the only easy and non-invasive way
   * to communicate with user is via Toast messages. These are used just to grab user attention and
   * to direct them to Logcat where a much more detailed report will be printed.
   */
  private fun showToast(heapAnalysis: HeapAnalysis) {
    mainHandler.post {
      val resumedActivity = InternalLeakCanary.resumedActivity ?: return@post
      val message: String = when (heapAnalysis) {
        is HeapAnalysisSuccess -> {
          application.getString(
              R.string.leak_canary_tv_analysis_success,
              heapAnalysis.applicationLeaks.size,
              heapAnalysis.libraryLeaks.size
          )
        }
        is HeapAnalysisFailure -> application.getString(R.string.leak_canary_tv_analysis_failure)
      }
      TvToast.makeText(resumedActivity, message).show()
    }
  }

  /**
   * Android TV with API 26+ has a bug where the launcher icon doesn't appear, so users won't know how
   * to launch LeakCanary Activity.
   * This method prints an adb command that launched LeakCanary into the logcat
   */
  private fun printIntentInfo() {
    val leakClass = LeakActivity::class.java
    SharkLog.d {
      """====================================
  ANDROID TV LAUNCH INTENT
  ====================================
  Run the following adb command to display the list of leaks:
  
  adb shell am start -n "${application.packageName}/${leakClass.`package`?.name}.LeakLauncherActivity"
  ===================================="""
    }
  }

  companion object {
    fun create(): OnHeapAnalyzedListener =