Exit from app android code

Finding the reason for the exit in Android Application

When working with an Android application, we might have to keep an eye on crashes or unwanted ways that the user exits the app. We use many third-party libraries to log exits in android.

Now, with Android R, we can log the exits in our app which can help us fix any issue that might exist in our app.

In this blog, we are going to talk, how we can log the exits of the user from our application.

Let’ s first discuss the type of crashes and exits we might see in our application. There can be a crash for an exception or maybe there might be an ANR that might lead your app to crash and drop users out of the application. The users might also exit the app intentionally when they have completed using the app.

Consider an example, let us say we are using WhatsApp and we want to log all the actions when a user exits the app. It can be a crash or an exception, or maybe a user action to close the app.

So, to get all the information we are going to use the ActivityManager .

But before that,

What is ActivityManager?

ActivityManager gives information about and interacts with, activities, services, and the containing process. Methods in this class give us certain information that we can use to debug our application.

So, first, I will create a project with MainActivity like,

Now, we will initialize the ActivityManager like,

Now, we will use ActivityManager to get the list of historic exit reasons for the app. To get the list, we will use,

Here, getHistoricalProcessExitReasons takes three parameters,

  • Package name: Here, we passed the package name of our application
  • PID: We passed 0 as default to get all the reasons
  • Size: The size of the list of exit reasons. So, we will get a list of type ApplicationExitInfo with only one item.

Here the exitList returns the history of exit, not the exit information in real-time as it provides the historical data.

Now, let’s first set up the exitList to return us the cause and reason of our crashes.

In our onCreate(), I will add,

Since we have only one item in the list lastExitInformation will get the value from the list using .first()

Читайте также:  Защита папок для андроидов

Now, we will Log the exit reasons, time and description using,

  • lastExitInformation will return an integer which corresponds to the reason of the crash
  • Timestamp returns Time in Epoch and,
  • The description returns the descriptive version of the crash.

Now, let’s add a TextView in XML file like,

and set the reason of crash to the textView using,

We are done setting up everything to get the historic exit reasons. Now, let’s start logging the reasons.

Case 1:

When we close the app from the recent app’s tray and then reopen the app again we would see the following log,

  • Reason code is 10 which means, REASON_USER_REQUESTED.
  • We got timestamp as well in our log and,
  • We got the description as remove a task, as we removed the app from the recent app’s tray.

We can also see the reason code in the textView .

The reason code and its meaning are,

So, for example, if we get a crash the reason code would be 4 according to the above table.

Case 2:

When we get a crash in our application. So, first, let’s introduce a crash in our application. We will create a button using,

and on click of textView, we will invoke the button’s click listener like,

This would lead to a crash of our application because the button is not mapped to any widget in XML.

When we reopen the app again, the app will generate a log,

Here, the reason code is 4, which maps to REASON_CRASH from the above table and the description also specifies crash.

If any exception occurs as well, the reason code would be REASON_CRASH

Case 3:

Let us terminate the JVM using System.exit().

So, In on the click of textView, we will add System.exit() like,

This will terminate the app. When we reopen the app, it will generate a log like,

Here, we won’t see any description but the reason code is 1 which maps to REASON_EXIT_SELF. This means it terminated itself.

Case 4:

When our application gets ANR.

So, to generate an ANR we will run an infinite loop on click of textView using,

So, when App gets an ANR the Log generated would be,

Here, the reason code is 6, which means REASON_ANR.

These are a few cases where we can log our exits form our application.

In this blog, we are using the maximum size as 1. If we change it to any number more then 1, let’s say maybe 10. It will return the list of last 10 exit reasons information. To set max size to 10, we update the code,

This is how we can use getHistoricalProcessExitReasons to get the reasons for the exit of the app which might be very useful for developers to understand the user’s behavior of using the app or maybe checking for crashes.

Читайте также:  Install android samsung tab

Источник

Разбираемся с Clean Code в Android

Вы читаете эту статью по двум причинам. Первая — Вы программист, вторая — Вы хотите быть лучшим программистом.

Представьте, что Вы находитесь в библиотеке и ищете какие-то книги. Если библиотека сортирована, имеет категории книг, то вы быстро отыщите нужную Вам. Кроме того, крутой дизайн интерьера и архитектура сделает пребывание в этой библиотеке довольно комфортным для Вас.

Как и при написании книг, если вы хотите создать что-то великое, то вы должны знать как писать и как организовывать свой код. Если у вас есть члены команды или кто-то еще, у кого есть Ваш (устаревший) код, им просто нужно увидеть имена переменных или пакеты или классы, и они сразу поймут. Им не нужно говорить «Е**л» я этот код и начинать его снова с нуля.

Что такое «Чистый Код»?

Когда я писал этот код, только Бог и я знал как он работает!
Теперь только Бог знает это!

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

Всего потрачено часов: 567

Как Вы можете видеть, недостаточно закончить разработку быстрее. Если в будущем в этом коде не смогут разобраться, то это так же станет техническим долгом.

Ваш код имеет состояние «Чистый», если его может понять каждый член Вашей команды. Чистый код может быть прочитан и улучшен любым разработчиком, отличным от первоначального автора. С пониманием приходит читаемость, изменяемость, расширяемость и ремонтопригодность.

Я должен заботиться об этом?

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

Признаки Чистого кода

Отличие между хорошим программистом и профессионалом в том, что профессиональный программист понимает, что понятность кода первостепенна. Профессионал использует эту силу для написания кода, который понятен всем — Robert C. Martin

Пишите осознанные имена

Выбор хорошего имени, может занять много времени, но в последствии оно сэкономит больше. Имя переменной, функции, класса должно отвечать на все значимые вопросы. Оно должно рассказать Вам, почему оно существует, зачем оно нужно и как его использовать. Если имя требует комментария, то имя не раскрывает своего предназначения

Имена классов

Классы и объекты должны быть существительными, например Сustomer, WikiPage, Account, and AddressParser. Избегайте таких слов как Manager, Processor, Data, или Info. Помните так же, что имя класса не должно быть глаголом.

Имена методов

Имена методов же должны быть глаголами, например postPayment, deletePage или save. Модификаторы доступа, предикаты должны быть названы по их значению и с префиксом get, set и согласно стандарту JavaBean.

Перед тем, как мы продолжим сделайте небольшой перерыв, запаситесь кофе и печеньками

Окей, теперь перейдем к SOLID принципам

Пишите код, придерживаясь SOLID принципов

Эти принципы были разработаны дядюшкой Бобом, SOLID это аббревиатура, описывающая набор принципов, предназначенных для написания хорошего кода.

Читайте также:  Как скрыть wifi сеть android

Принцип единственную ответственности (S)

Это означает, что каждый класс должен нести только одну ответственность. Никогда не должно быть более одной причины для изменения класса. Не надо добавлять все в свой класс, просто потому что Вы можете это сделать. Разбивайте большие классы на более маленькие и избегайте God Classes.

У нас есть RecyclerView.Adapter с бизнес логикой внутри onBindViewHolder

Это делает RecyclerView.Adapter не имеющим единственную ответственность, потому что он содержит бизнес логику внутри onBindViewHolder. Этот метод отвечает только за вставку данных во view.

Принцип открытости/закрытости (О)

Программные сущности должны быть открыты для расширения, но закрыты для модификации. Это означает, что если Вы разрабатываете класс А и ваши коллеги захотят изменить функцию внутри этого класса. Они смогут легко это сделать, расширив этот класс без изменения самого класса.
Простой пример класс RecyclerView.Adapter. Вы можете с легкостью расширить его и создать свой собственный адаптер с нестандартным поведением без модификации самого RecyclerView.Adapter.

Принцип подстановки Барбары Лисков (L)

Дочерний класс должен дополнять родительский, а не изменять его. Это означает, что подкласс должен переопределять методы родительского, которые не нарушают функциональность этого родительского класса. Например мы создаем интерфейс класса, который имеет onClick() слушатель а затем вы применяете слушатель в MyActivity и даете ему действие Toast, когда вызывается onClick ().

Принцип разделения интерфейса

Этот принцип гласит, что клиент не должен быть зависим от методов, которые он не использует.
Это означает, что если Вы хотите написать класс А и добавить в него функциональность другого класса В. Нет необходимости переопределять все классы А внутри класса В.

Пример: в нашей активити, нам нужно реализовать SearchView.OnQueryTextListener(), но нам нужен только onQuerySubmit() метод.

Как мы это сделаем? Легко! Просто создадим callback и класс, расширяющий SearchView.OnQueryTextListener()

И вот так мы добавим это к нашей view

Или так, используя Extension Function в Kotlin

Принцип инверсии зависимостей

Зависимость на абстракциях, без зависимости на что-то конкретное.
Определение инверсии зависимостей от дядюшки Боба состоит из двух понятий.

Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба должны быть завязаны на абстракциях. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. Модули высоких уровней, которые реализуют комплексную логику, должны быть легко переиспользуемы без изменений в модулях нижнего уровня. Для этого Вам нужно ввести абстракцию, которая отделяет модули верхнего и нижнего уровней друг от друга.

Простой пример этого MVP паттерн. У Вас есть объект интерфейсов, который помогает Вам общаться с конкретными классами. Что имеется ввиду — классам UI (Activity/Fragment) не нужно знать фактическую реализацию методов презентера. Таким образом, если Вы делаете изменения внутри презентера, UI классы не должны волновать эти изменения

Давайте взглянем на пример

А теперь на активити

Таким образом мы создаем интерфейс, который абстрагирует реализацию презентатора, и наш класс view сохраняет ссылку на PresenterInterface.

Источник

Оцените статью