Меняем стандартный диалог сбоя приложения в Android на собственный экран

Автор оригинала: Mustufa Ansari
  • Перевод

Как вместо стандартного диалогового окна о сбое использовать собственный экран с сообщением об ошибке

Будущих учащихся на курсе "Android Developer. Basic" приглашаем посетить открытый вебинар на тему "Приложение под Android на Kotlin за 1,5 часа"


А пока делимся традиционным полезным переводом.


Не знаю, как вам, но мне бывает очень стыдно, когда я передаю свое приложение на проверку тестировщику или клиенту и в приложении возникает сбой. Это весьма неприятный момент.

«Живи так, как будто ты умрешь завтра. Учись так, как будто ты будешь жить вечно».

Мне не нравится стандартное диалоговое окно, которое отображается при сбое приложения. Поэтому я нашел интересную библиотеку, которая позволяет отображать собственный экран с сообщением об ошибке вместо стандартного диалогового окна.

Давайте разберемся, как это сделать.

Что нам потребуется?

  1. Kotlin

  2. Android Studio

  3. Та самая библиотека.

После создания нового проекта добавьте в файл build.gradle(:app) следующую зависимость:

implementation 'cat.ereza:customactivityoncrash:2.3.0'

Создадим макет собственного экрана сбоя. Например, такой:

Макет собственного экрана сбоя
Макет собственного экрана сбоя

Эту картинку, изображающую сбой, я скачал отсюда.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/errorText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:fontFamily="sans-serif"
        android:text="@string/ouch_something_went_wrong"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textStyle="bold" />


    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ic_error_img" />


    <com.google.android.material.button.MaterialButton
        android:id="@+id/restartApp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp"
        android:text="Restart App"
        android:textAllCaps="false" />

</RelativeLayout>

Как стать успешным разработчиком для Android

Следуйте этому плану, если хотите стать профессиональным разработчиком для Android

medium.com

Давайте добавим код, который отслеживает событие сбоя и отображает собственный экран сбоя вместо стандартного диалогового окна Android.

package com.example.customerrorscreen

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import cat.ereza.customactivityoncrash.CustomActivityOnCrash
import kotlinx.android.synthetic.main.activity_error.*

class ErrorActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_error)


        /** you can log the reason of crash by adding this line of code
         *  CustomActivityOnCrash.getStackTraceFromIntent(intent)
         */

        //getting crashing intent
        val config = CustomActivityOnCrash.getConfigFromIntent(intent)

        /**
         * If config is null or not getting an intent simply finish the app
         */
        if (config == null) {
            finish()
            return
        }
        
        if (config.isShowRestartButton && config.restartActivityClass != null) {
            restartApp.text = "Restart App"
            restartApp.setOnClickListener {
                CustomActivityOnCrash.restartApplication(
                    this,
                    config
                )
            }
        } else {
            restartApp.text = "Close App"
            restartApp.setOnClickListener {
                CustomActivityOnCrash.closeApplication(
                    this,
                    config
                )
            }
        }

    }
}

Нужно создать класс приложения, который будет зарегистрирован в манифесте Android с целью глобальной регистрации библиотеки обработки сбоев в приложении.

package com.example.customerrorscreen

import android.app.Application
import cat.ereza.customactivityoncrash.config.CaocConfig


/**
 * Created by  Mustufa on 04/11/2020.
 * Email : mustufaayub82@gmail.com
 */
class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()
        CaocConfig.Builder.create()
            .trackActivities(true)
            .errorActivity(ErrorActivity::class.java)
            .apply()
    }
}

Добавим этот класс в файл AndroidManifest.xml, используя атрибут name.

AndroidManifest.xml
AndroidManifest.xml

Теперь перейдем к файлу MainActivity.kt и поэкспериментируем с нашей новой возможностью. Мы должны вызвать сбой в приложении, чтобы увидеть наш экран сбоя. Я добавлю код, вызывающий сбой приложения, в метод onCreate.

var array = mutableListOf<String>()
array[0] = "Hello"
findViewById<TextView>(R.id.textView).text = array[1]

При выполнении этого кода будет сгенерировано исключение IndexOutOfBoundException и в приложении возникнет сбой.

Запустим приложение.

Исходный код можно скачать отсюда.


Узнать подробнее о курсе "Android Developer. Basic".

Записаться на открытый урок на тему "Приложение под Android на Kotlin за 1,5 часа".

OTUS. Онлайн-образование
Цифровые навыки от ведущих экспертов

Комментарии 3

    +2
    феерическая исуя
    github.com/Ereza/CustomActivityOnCrash/issues/58
    Ни каких претензий к переводчику.
    Но как понимаю ни автор, ни те кто повелся и внедрил эту либу не догоняют,
    что логов в консоле разработчика не будет

      0

      А у вас не подключен Firebase Crashlytics или Sentry?
      Сторонние средства позволяют реагировать на крэши оперативнее, какой ещё смысл остался смотреть на крэши в саму консоль разработчика?

        0
        возможно автор либы тоже в курсе. И с этим я ошибся.
        И как kolipass, тоже считает что в продакшене креш аналитика должна собираться.
        А «феерия» в том, что кто-то добавил библиотеку релизную сборку для пользователей.

        С моей точки зрения данная библиотека имеет очень узкую сферу применения.
        Приложение должно работать с USB и разработчику не хочется связываться с WiFI ADB.
        Только тогда расширенный отладочный креш репорт либы становится актуальным.
        Главное что я имел в виду:
        Эту библиотеку с моей точки зрения имеет смысл подключать только в дебаг сборках.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое