- How to detect Android application open and close: Background and Foreground events.
- Detecting App Lifecycle Evnts
- Backgrounding
- Foregrounding
- Implementing a Foreground and Background Handler
- AppLifecycleHandler
- Update: Using Android Architecture Components
- How to Close Apps on Android
- Shut off running apps to free up memory and declutter
- Closing Apps Isn’t Usually Necessary
- How to Close Apps on Android From the Home Screen
- How to Close Apps Using the Apps Manager
- How to Shut Down Running Services on Android
- Android UI thread
- Рассмотрим взаимодействие системы Android с компонентами приложения.
How to detect Android application open and close: Background and Foreground events.
Dec 17, 2017 · 4 min read
This question seems to come up a lot. Especially if you are just starting out with Android developme n t. It’s simply because there is nothing obvious built into the Android SDK enabling developers to hook into application lifecycle events. Activities and Fragments have all the callbacks under the sun to detect lifecycle change, but there is nothing for the whole application. So how do you detect when a user backgrounds and foregrounds your app. This is an example of how your could detect Application lifecycle events. Feel free to adjust and enhance it to suit your needs, but this idea should be enough to work for most applications with one caveat, it will only work for Android API level 14+(IceCreamSandwich 🍦🥪).
Detecting App Lifecycle Evnts
Backgrounding
ComponentCallbacks2 — Looking at the documentation is not 100% clear on how you would use this. However, take a closer look and you will noticed the onTrimMemory method passes in a flag. These flags are typically to do with the memory availability but the one we care about is TRIM_MEMORY_UI_HIDDEN. By checking if the UI is hidden we can potentially make an assumption that the app is now in the background. Not exactly obvious but it should work.
Foregrounding
ActivityLifecycleCallbacks — We can use this to detect foreground by overriding onActivityResumed and keeping track of the current application state (Foreground/Background).
Implementing a Foreground and Background Handler
First, lets create our interface that will be implemented by a custom Application class. Something as simple as this:
Next, we need a class that is going to implement the ActivityLifecycleCallbacks and ComponentCallbacks2 we discussed earlier. So lets create an AppLifecycleHandler and implement those interfaces and override the methods required. And lets take an instance of the LifecycleDelegate as a constructor parameter so we can call the functions we defined on the interface when we detect a foreground or background event.
We outlined earlier that we could use onTrimMemory and the TRIM_MEMORY_UI_HIDDEN flag to detect background events. So lets do that now.
Add this into the onTrimMemory method callback body
So now we have the background event covered lets handle the foreground event. To do this we are going to use the onActivityResumed. This method gets called every time any Activity in your app is resumed, so this could be called multiple times if you have multiple Activities. What we will do is use a flag to mark it as resumed so subsequent calls are ignored, and then reset the flag when the the app is backgrounded. Lets do that now.
So here we create a Boolean to flag the application is in the foreground. Now, when the application onActivityResumed method is called we check if it is currently in the foreground. If not, we set the appInForeground to true and call back to our lifecycle delegate ( onAppForegrounded()). We just need to make one simple tweak to our onTrimMemory method to make sure that sets appInForeground to false.
Now we are ready to use our AppLifecycleHandler class.
AppLifecycleHandler
Now all we need to do is have our custom Application class implement our LifecycleDelegate interface and register.
And there you go. You now have a way of listening to your app going into the background and foreground.
This is only supposed to be used as an idea to adapt from. The core concept using onTrimMemory and onActivityResumed with some app state should be enough for most applications, but take the concept, expand it and break things out it to fit your requirements. For the sake of brevity I won’t go into how we might do multiple listeners in this post, but with a few tweaks you should easily be able to add a list of handlers or use some kind of observer pattern to dispatch lifecycle events to any number of observers. If anyone would like me to expand on this and provide a multi listener solution let me know in the comments and I can set something up in the example project on GitHub.
Update: Using Android Architecture Components
Thanks to Yurii Hladyshev for the comment.
If you are using the Android Architecture Components library you can use the ProcessLifecycleOwner to set up a listener to the whole application process for onStart and onStop events. To do this, make your application class implement the LifecycleObserver interface and add some annotations for onStop and onStart to your foreground and background methods. Like so:
Источник
How to Close Apps on Android
Shut off running apps to free up memory and declutter
To close apps on Android means to shut the apps down. You might shut down an app if it isn’t responding normally, if your phone or tablet is low on memory, or to clear up the screen.
Closing Apps Isn’t Usually Necessary
It’s not usually required that you shut down apps on Android because your device should handle the apps appropriately, shuffling memory back and forth between apps you’re actively using and the ones running in the background. Constantly shutting down apps might make your device run slower. However, if there’s a reason you want to clear the apps, you can do so easily.
Shutting off, killing, or clearing away Android apps isn’t the same as deleting them. You need to uninstall an Android app to remove it completely.
These directions should work no matter who made your tablet or phone—Google, Samsung, Xiaomi, etc.
How to Close Apps on Android From the Home Screen
There are a couple of ways to shut off apps. You can close running apps from the Home screen or from the device settings.
The quickest way is from the Home screen at any time:
Start by viewing all running apps. How you do this depends on your phone and the Android version. If you’re not sure how your device shows running apps, try the different methods that are available:
- Swipe up from the bottom of the screen (but don’t swipe too far up or the app drawer opens).
- Tap the small square icon on the bottom of the screen.
- Press the physical button on the bottom of your phone or tablet that looks like two overlapping rectangles. You might not see it light up until you press in that area next to the Home button.
- On Samsung Galaxy devices, press the Recent Apps button to the left of the Home button.
Swipe up and down or left and right (depending on your phone) to find the app you want to close down.
Swipe up on the app you want to kill, as if you were throwing it off the screen. This works if your apps are listed horizontally.
Or, for vertically listed apps, swipe the app left or right to close it immediately.
On some devices, there’s an exit button in the upper-right corner of each app when in this view, and you can tap it to close the app. If you see a three-lined button at the bottom with a small x on it, tap it to close all the recently opened apps.
Some devices have a Clear all option if you swipe all the way to the left. Tapping that kills all the apps at once.
Repeat steps 2 and 3 to close the other running apps. When you’re finished, select an empty space next to the edge of the screen or press the Home button.
How to Close Apps Using the Apps Manager
Your phone or tablet has a built-in manager for apps that you should use if you need to close background apps (apps that are running but don’t show up when you follow the method above).
When you use the settings to close running apps, there are more options than what you find in the swiping method. This option isn’t as friendly and is geared more toward killing unresponsive apps rather than exiting gracefully.
Open the settings and tap Apps & notifications. If you don’t see that, look for Apps, App Management, Application manager, or General > Apps.
Tap See all apps and then locate the problem app that you want to shut down. If you don’t see that option, you may be viewing a list of the apps on your device, in which case you can scroll to find the one you want to close.
Select the app and choose Force stop.
Depending on your device, this screen is also where you can uninstall the app if you’re not sure why you have it in the first place.
Tap OK or Force stop to confirm that you want to kill the running app.
Once the app has stopped, you can open it again normally. However, the destructive nature of forcing an app to close down may cause some corruption or unintended behavior.
How to Shut Down Running Services on Android
Services are usually not something the average person needs to deal with, especially considering that the ability to do so isn’t available by default. However, if you know what you’re doing, and you need to terminate a service that a particular app is running, it’s a straightforward process.
Enable developer mode. This is a special mode that lets you view and edit settings that a normal user can’t see.
Go to Settings > System > Advanced, then tap Developer options. Some older Android devices store these options in Settings > System.
Select Running services, and scroll through the list to find and select the app that’s running the service you want to kill.
Choose Stop next to the service you want to end. Depending on your device, you might need to press OK to confirm.
Источник
Android UI thread
Большая часть кода Android приложения работает в контексте компонент, таких как Activity, Service, ContentProvider или BroadcastReceiver. Рассмотрим, как в системе Android организованно взаимодействие этих компонент с потоками.
При запуске приложения система выполняет ряд операций: создаёт процесс ОС с именем, совпадающим с наименованием пакета приложения, присваивает созданному процессу уникальный идентификатор пользователя, который по сути является именем пользователя в ОС Linux. Затем система запускает Dalvik VM где создаётся главный поток приложения, называемый также «поток пользовательского интерфейса (UI thread)». В этом потоке выполняются все четыре компонента Android приложения: Activity, Service, ContentProvider, BroadcastReceiver. Выполнение кода в потоке пользовательского интерфейса организованно посредством «цикла обработки событий» и очереди сообщений.
Рассмотрим взаимодействие системы Android с компонентами приложения.
Activity. Когда пользователь выбирает пункт меню или нажимает на экранную кнопку, система оформит это действие как сообщение (Message) и поместит его в очередь потока пользовательского интерфейса (UI thread).
Service. Исходя из наименования, многие ошибочно полагают, что служба (Service) работает в отдельном потоке (Thread). На самом деле, служба работает так же, как Activity в потоке пользовательского интерфейса. При запуске локальной службы командой startService, новое сообщение помещается в очередь основного потока, который выпонит код сервиса.
BroadcastReceiver. При создании широковещательного сообщения система помещает его в очередь главного потока приложения. Главный поток позднее загрузит код BroadcastReceiver который зарегистрирован для данного типа сообщения, и начнёт его выполнение.
ContentProvider. Вызов локального ContentProvider немного отличается. ContentProvider также выполняется в основном потоке но его вызов является синхронным и для запуска кода ContentProvider не использует очередь сообщений.
Исходя из вышесказанного можно заметить, что если главный поток в данный момент обрабатывает пользовательский ввод или выполняет иное действие, выполнение кода, полученного в новом сообщении, начнётся только после завершения текущей операции. Если какая либо операция в одном из компонентов потребует значительного времени выполнения, пользователь столкнётся или с анимацией с рывками, или с неотзывчивыми элементами интерфейса или с сообщением системы «Приложение не отвечает» (ANR).
Для решения данной проблемы используется парадигма параллельного программирования. В Java для её реализации используется понятие потока выполнения (Thread).
Thread: поток, поток выполнения, иногда ещё упоминается как нить, можно рассматривать как отдельную задачу, в которой выполняется независимый набор инструкций. Если в вашей системе только один процессор то потоки выполняются поочередно (но быстрое переключение системы между ними создает впечатление параллельной или одновременной работы). На диаграмме показано приложение, которое имеет три потока выполнения:
Но, к сожалению, для взаимодействия с пользователем, от потока мало пользы. На самом деле, если вы внимательно посмотрите на диаграмму выше, вы поймёте, что как только поток выполнить все входящие в него инструкции он останавливается и перестаёт отслеживать действия пользователя. Чтобы избежать этого, нужно в наборе инструкций реализовать бесконечный цикл. Но возникает проблема как выполнить некое действие, например отобразить что-то на экране из другого потока, иными словами как вклиниться в бесконечный цикл. Для этого в Android можно использовать Android Message System. Она состоит из следующих частей:
Looper: который ещё иногда ещё называют «цикл обработки событий» используется для реализации бесконечного цикла который может получать задания используется. Класс Looper позволяет подготовить Thread для обработки повторяющихся действий. Такой Thread, как показано на рисунке ниже, часто называют Looper Thread. Главный поток Android на самом деле Looper Thread. Looper уникальны для каждого потока, это реализованно в виде шаблона проектирования TLS или Thread Local Storage (любопытные могут посмотреть на класс ThreadLocal в Java документации или Android).
Message: сообщение представляет собой контейнер для набора инструкций которые будут выполнены в другом потоке.
Handler: данный класс обеспечивает взаимодействие с Looper Thread. Именно с помощью Handler можно будет отправить Message с реализованным Runnable в Looper, которая будет выполнена (сразу или в заданное время) потоком с которым связан Handler. Код ниже иллюстрирует использование Handler. Этот код создаёт Activity которая завершиться через определённый период времени.
HandlerThread: написание кода потока реализующего Looper может оказаться не простой задачей, чтобы не повторять одни и те же ошибки система Android включает в себя класс HandlerThread. Вопреки названию этот класс не занимается связью Handler и Looper.
Практическую реализацию данного подхода можно изучить на примере кода класса IntentService, данный класс хорошо подходит для выполнения асинхронных сетевых или иных запросов, так как он может принимать задания одно за другим, не дожидаясь полной обработки текущего, и завершает свою работу самостоятельно.
Выполнение операций в отдельном потоке, не означает, что вы можете делать все что угодно, не влияя на производительность системы. Никогда не забывайте, что написанный вами код работает на машинах, как правило, не очень мощных. Поэтому всегда стоит использовать возможности предоставляемые системой для оптимизации.
Подготовлено на основе материалов AndroidDevBlog
Источник