Служба (Service)
Службы (Сервисы) в Android работают как фоновые процессы и представлены классом android.app.Service. Они не имеют пользовательского интерфейса и нужны в тех случаях, когда не требуется вмешательства пользователя. Сервисы работают в фоновом режиме, выполняя сетевые запросы к веб-серверу, обрабатывая информацию, запуская уведомления и т.д. Служба может быть запущена и будет продолжать работать до тех пор, пока кто-нибудь не остановит её или пока она не остановит себя сама. Сервисы предназначены для длительного существования, в отличие от активностей. Они могут работать, постоянно перезапускаясь, выполняя постоянные задачи или выполняя задачи, требующие много времени.
Клиентские приложения устанавливают подключение к службам и используют это подключение для взаимодействия со службой. С одной и той же службой могут связываться множество клиентских приложений.
Android даёт службам более высокий приоритет, чем бездействующим активностям, поэтому вероятность того, что они будут завершены из-за нехватки ресурсов, заметно уменьшается. По сути, если система должна преждевременно завершить работу запущенного сервиса, он может быть настроен таким образом, чтобы запускаться повторно, как только станет доступно достаточное количество ресурсов. В крайних случаях прекращение работы сервиса (например, задержка при проигрывании музыки) будет заметно влиять на впечатления пользователя от приложения, и в подобных ситуациях приоритет сервиса может быть повышен до уровня активности, работающей на переднем плане.
Используя сервис, можете быть уверены, что ваши приложения продолжат работать и реагировать на события, даже если они в неактивном состоянии. Для работы службам не нужен отдельный графический интерфейс, как в случае с активностями, но они по-прежнему выполняются в главном потоке хода приложения. Чтобы повысить отзывчивость вашего приложения, нужно уметь переносить трудоёмкие процессы (например, сетевые запросы) в фоновые потоки, используя классы Thread и AsyncTask.
Службы идеально подходят для проведения постоянных или регулярных операций, а также для обработки событий даже тогда, когда активности вашего приложения невидимы, работают в пассивном режиме или закрыты.
Сервисы запускаются, останавливаются и контролируются из различных компонентов приложения, включая другие сервисы, активности и приёмники широковещательных намерений. Если ваше приложение выполняет задачи, которые не зависят от прямого взаимодействия с пользователем, сервисы могут стать хорошим выбором.
Запущенные сервисы всегда имеют больший приоритет, чем бездействующие или невидимые активности, поэтому менее вероятно, что их работа завершится преждевременно при распределении ресурсов. Единственная причина, почему Android может досрочно остановить Сервис, — выделение дополнительных ресурсов для компонентов, работающих на переднем плане (как правило, для активностей). Если такое случится, ваш сервис автоматически перезапустится, когда будет достаточно доступных ресурсов.
Когда сервис напрямую взаимодействует с пользователем (например, проигрывая музыку), может понадобиться повысить его приоритет до уровня активностей, работающих на переднем плане. Это гарантия того, что сервис завершится только в крайнем случае, но при этом снижается его доступность во время выполнения, мешая управлять ресурсами, что может испортить общее впечатление от приложения.
Приложения, которые регулярно обновляются, но очень редко или нерегулярно взаимодействуют с пользователем, можно назвать первыми кандидатами на реализацию в виде сервисов. Проигрыватели MP3 и приложения, отслеживающие спортивные результаты, — примеры программ, которые должны постоянно работать и обновляться без необходимости отображать активность.
Создание службы
Чтобы определить службу, необходимо создать новый класс, расширяющий базовый класс Service. Можно воспользоваться готовым мастером создания класса для сервиса в Android Studio. Щёлкаем правой кнопкой мыши на папке java (или на имени пакета) и выбираем New | Service | Service:
В следующем окне выбираем имя сервиса (флажки оставляем) и нажимаем кнопку Finish.
// Kotlin package ru.alexanderklimov.service import android.app.Service import android.content.Intent import android.os.IBinder class MyService : Service() < override fun onBind(intent: Intent): IBinder < TODO("Return the communication channel to the service.") >>
// Java package ru.alexanderklimov.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service < public MyService() < >@Override public IBinder onBind(Intent intent) < // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); >>
При этом сервис автоматически зарегистрируется в манифесте в секции .
Если бы мы убрали флажки на экране мастера, то оба атрибута имели бы значение false. Например, атрибут exported даёт возможность другим приложениям получить доступ к вашему сервису.
Имеются и другие атрибуты, например, permission, чтобы сервис запускался только вашим приложением.
Также вы можете обойтись без мастера и создать вручную класс сервиса и запись в манифесте, теперь вы знаете, из чего он состоит.
Жизненный цикл служб
Подобно активностям служба имеет свои методы жизненного цикла:
Для быстрого создания заготовок нужных методов используйте команду меню Code | Override Methods. или набирайте сразу имя метода, используя автодополнение.
Реализуя эти методы обратного вызова в своей службе, вы можете контролировать жизненные циклы службы. В полном жизненном цикле службы существует два вложенных цикла:
- полная целая жизнь службы — промежуток между временем вызова метода onCreate() и временем возвращения onDestroy(). Подобно активности, для служб производят начальную инициализацию в onCreate() и освобождают все остающиеся ресурсы в onDestroy()
- активная целая жизнь службы — начинается с вызова метода onStartCommand(). Этому методу передаётся объект Intent, который передавали в метод startService().
Из своего приложения службу можно запустить вызовом метода Context.startService(), остановить через Context.stopService(). Служба может остановить сама себя, вызывая методы Service.stopSelf() или Service.stopSelfResult().
Можно установить подключение к работающей службе и использовать это подключение для взаимодействия со службой. Подключение устанавливают вызовом метода Context.bindService() и закрывают вызовом Context.unbindService(). Если служба уже была остановлена, вызов метода bindService() может её запустить.
Методы onCreate() и onDestroy() вызываются для всех служб независимо от того, запускаются ли они через Context.startService() или Context.bindService().
Если служба разрешает другим приложениям связываться с собой, то привязка осуществляется с помощью дополнительных методов обратного вызова:
- IBinder onBind(Intent intent)
- onUnbind(Intent intent)
- onRebind(Intent intent)
В метод обратного вызова onBind() передают объект Intent, который был параметром в методе bindService(), а в метод обратного вызова onUnbind() — объект Intent, который передавали в метод unbindService(). Если служба разрешает связывание, метод onBind() возвращает канал связи, который используют клиенты, чтобы взаимодействовать со службой. Метод обратного вызова onRebind() может быть вызван после onUnbind(), если новый клиент соединяется со службой.
Запуск сервиса и управление его перезагрузкой
В большинстве случаев также необходимо переопределить метод onStartCommand(). Он вызывается каждый раз, когда сервис стартует с помощью метода startService(), поэтому может быть выполнен несколько раз на протяжении работы. Вы должны убедиться, что ваш сервис это предусматривает.
Метод onStartCommand() заменяет устаревший метод onStart(), который использовался в Android 2.0. В отличие от onStart() новый метод позволяет указать системе, каким образом обрабатывать перезапуски, если сервис остановлен системой без явного вызова методов stopService() или stopSelf().
@Override public int onStartCommand(Intent intent, int flags, int startId)
Службы запускаются в главном потоке приложения; это значит, что любые операции, выполняющиеся в обработчике onStartCommand(), будут работать в контексте главного потока GUI. На практике при реализации сервиса в методе onStartCommand() создают и запускают новый поток, чтобы выполнять операции в фоновом режиме и останавливать сервис, когда работа завершена.
Такой подход позволяет методу onStartCommand() быстро завершить работу и даёт возможность контролировать поведение сервиса при его повторном запуске, используя одну из констант.
- START_STICKY — Описывает стандартное поведение. Похоже на то, как был реализован метод onStart() в Android 2.0. Если вы вернёте это значение, обработчик onStartCommand() будет вызываться при повторном запуске сервиса после преждевременного завершения работы. Обратите внимание, что аргумент Intent, передаваемый в onStartCommand(), получит значение null. Данный режим обычно используется для служб, которые сами обрабатывают свои состояния, явно стартуя и завершая свою работу при необходимости (с помощью методов startService() и stopService()). Это относится к службам, которые проигрывают музыку или выполняют другие задачи в фоновом режиме
- START_NOT_STICKY — Этот режим используется в сервисах, которые запускаются для выполнения конкретных действий или команд. Как правило, такие службы используют stopSelf() для прекращения работы, как только команда выполнена. После преждевременного прекращения работы службы, работающие в данном режиме, повторно запускаются только в том случае, если получат вызовы. Если с момента завершения работы Сервиса не был запущен метод startService(), он остановится без вызова обработчика onStartCommand(). Данный режим идеально подходит для сервисов, которые обрабатывают конкретные запросы, особенно это касается регулярного выполнения заданных действий (например, обновления или сетевые запросы). Вместо того, чтобы перезапускать сервис при нехватке ресурсов, часто более целесообразно позволить ему остановиться и повторить попытку запуска по прошествии запланированного интервала
- START_REDELIVER_INTENT — В некоторых случаях нужно убедиться, что команды, которые вы посылаете сервису, выполнены. Этот режим — комбинация предыдущих двух. Если система преждевременно завершила работу сервиса, он запустится повторно, но только когда будет сделан явный запрос на запуск или если процесс завершился до вызова метода stopSelf(). В последнем случае вызовется обработчик onStartCommand(), он получит первоначальное намерение, обработка которого не завершилась должным образом.
Обратите внимание, что при окончании всех операций каждый из этих режимов требует явной остановки сервиса с помощью методов stopService() или stopSelf().
Режим перезапуска, который вы указываете в качестве значения, возвращаемого методом onStartCommand(), будет влиять на параметры, передаваемые при последующих вызовах.
Изначально намерение выступает в качестве параметра, который передастся в метод startService() при запуске сервиса. После перезапуска системой он может иметь значение null (если установлен режим START_STICKY) или оригинальное (если установлен флаг START_REDELIVER_INTENT).
Параметр flag может помочь узнать, как именно был запущен сервис:
- START_FLAG_REDELIVERY — указывает на то, что параметр Intent повторно передан при принудительном завершении работы сервиса перед явным вызовом метода stopSelf()
- START_FLAG_RETRY — указывает на то, что сервис повторно запущен после непредвиденного завершения работы; передается в том случае, если ранее сервис работал в режиме START_STICKY
@Override public int onStartCommand(Intent intent, int flags, int startId) < if ((flags & START_FLAG_RETRY) == 0) < // TODO Если это повторный запуск, выполнить какие-то действия. >else < // TODO Альтернативные действия в фоновом режиме. >return Service.START_STICKY; >
Запуск и остановка служб
Начиная с Android 8.0 вы можете получить исключение IllegalStateException, если у приложения нет разрешения на запуск от системы.
Чтобы запустить службу, в клиентском приложении необходимо вызывать метод startService(). Существует два способа вызова службы:
- явный вызов;
- неявный вызов
Пример для явного вызова службы с именем MyService:
startService(new Intent(this, MyService.class));
Также можно явно определить службу, создав экземпляр класса этой службы.
Пример неявного вызова службы:
startService(new Intent(MyService.SERVICE_ACTION));
Чтобы использовать этот пример, необходимо включить константу SERVICE_ACTION, идентифицирующую службу, в класс MyService, например:
private static String SERVICE_ACTION = "ru.alexanderklimov.media.PLAYER";
Используйте фильтр намерений, чтобы зарегистрировать его как провайдера SERVICE_ACTION. Если служба потребует разрешений, которые не имеет ваше приложение, то запрос вызовет исключение SecurityException.
Как только сервис завершил выполнение тех действий, для которых он запускался, вы должны вызвать метод stopSelf() либо без передачи параметра, чтобы ускорить остановку работы, либо передав значение startId, чтобы убедиться, что задачи выполнены для всех экземпляров, запущенных с помощью вызова startService(), как показано в следующем фрагменте:
stopSelf(startId);
Явная остановка сервиса по завершении необходимых задач позволяет системе получать обратно ресурсы, которые в ином случае оставались бы заняты. Поскольку приоритет сервисов повышенный, система, как правило, не завершает их работу, поэтому её окончание по собственной инициативе может существенно улучшить эффективность использования ресурсов вашим приложением.
Для остановки работы используйте метод stopService(), передавая ему объект Intent, определяющий нужный сервис.
Если метод startService() вызывается для сервиса, который уже работает, обработчик onStartCommand(), принадлежащий объекту Service, будет вызван повторно. Вызовы startService() не накапливаются, поэтому единственный вызов метода stopService() завершит работу сервиса, неважно, сколько раз производился вызов startService().
Давайте создадим практическое приложение для работы со службой. Наша служба будет запускать на воспроизведение музыкальный файл, который будет проигрываться в фоновом режиме. Управлять службой можно будет из активности. Создайте новый проект. Для службы создайте отдельный класс PlayService. Служба будет загружать музыкальный файл sample.mp3 из каталога res/raw/ (разместите там свой MP3-файл).
PlayService.java
package ru.alexanderklimov.service; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; import android.support.annotation.Nullable; import android.widget.Toast; public class PlayService extends Service < private MediaPlayer mPlayer; @Nullable @Override public IBinder onBind(Intent intent) < return null; >@Override public void onCreate() < super.onCreate(); Toast.makeText(this, "Служба создана", Toast.LENGTH_SHORT).show(); mPlayer = MediaPlayer.create(this, R.raw.flower_romashka); mPlayer.setLooping(false); >// Устаревший метод // @Override // public void onStart(Intent intent, int startId) < // super.onStart(intent, startId); // Toast.makeText(this, "Служба запущена", // Toast.LENGTH_SHORT).show(); // mPlayer.start(); // >@Override public int onStartCommand(Intent intent, int flags, int startId) < Toast.makeText(this, "Служба запущена", Toast.LENGTH_SHORT).show(); mPlayer.start(); return super.onStartCommand(intent, flags, startId); >@Override public void onDestroy() < super.onDestroy(); Toast.makeText(this, "Служба остановлена", Toast.LENGTH_SHORT).show(); mPlayer.stop(); >>
Зарегистрируем службу в файле манифеста.
В файле разметки для активности определим две кнопки: Старт и Стоп:
В классе активности в обработчиках событий кнопок будем вызывать методы startService() и stopService() для управления службой.
package ru.alexanderklimov.service; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button btnStart = findViewById(R.id.button_start); final Button btnStop = findViewById(R.id.button_stop); // запуск службы btnStart.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < // используем явный вызов службы startService( new Intent(MainActivity.this, PlayService.class)); >>); // остановка службы btnStop.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < stopService( new Intent(MainActivity.this, PlayService.class)); >>); > >
Запущенная служба будет выполняться независимо от состояния активности, несмотря на то, что эти компоненты находятся в одном приложении: если её завершить, служба все равно останется работать.
Если вы хотите, чтобы сервис запускался и после перезагрузки устройства, то следует создать приёмник широковещательных сообщений и запустить в нём сервис.
public class BootBroadcast extends BroadcastReceiver < @Override public void onReceive(Context context, Intent intent) < context.startService(new Intent(context, TestService.class)); >>
Приёмник регистрируется в манифесте с именем действия BOOT_COMPLETED:
Пример для Kotlin
Класс для службы, которая будет генерировать случайные числа через определённый промежуток времени. Не забудьте прописать службу в манифесте.
package ru.alexanderklimov.service import android.app.Service import android.content.Intent import android.os.Handler import android.os.IBinder import java.util.* class RandomNumberService: Service() < private lateinit var mHandler: Handler private lateinit var mRunnable: Runnable override fun onBind(intent: Intent): IBinder? < throw UnsupportedOperationException("Not yet implemented") >override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int < // Send a notification that service is started toast("Service started.") // Do a periodic task mHandler = Handler() mRunnable = Runnable < showRandomNumber() >mHandler.postDelayed(mRunnable, 5000) return START_STICKY > override fun onDestroy() < super.onDestroy() toast("Service destroyed.") mHandler.removeCallbacks(mRunnable) >// Custom method to do a task private fun showRandomNumber() < val rand = Random() val number = rand.nextInt(100) toast("Random Number : $number") mHandler.postDelayed(mRunnable, 5000) >>
Разместите на экране активности три кнопки: запуск, остановка и статус службы. Код для активности.
package ru.alexanderklimov.service import android.app.ActivityManager import android.content.Context import android.content.Intent import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() < override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val serviceClass = RandomNumberService::class.java val intent = Intent(this, serviceClass) startButton.setOnClickListener < // If the service is not running then start it if (!isServiceRunning(serviceClass)) < startService(intent) >else < toast("Service already running.") >> stopButton.setOnClickListener < if (isServiceRunning(serviceClass)) < stopService(intent) >else < toast("Service already stopped.") >> statButton.setOnClickListener < if (isServiceRunning(serviceClass)) < toast("Service is running.") >else < toast("Service is stopped.") >> > // Custom method to determine whether a service is running private fun isServiceRunning(serviceClass: Class): Boolean < val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager // Loop through the running services for (service in activityManager.getRunningServices(Integer.MAX_VALUE)) < if (serviceClass.name == service.service.className) < // If the service is running then return true return true >> return false > > // Extension function to show toast message fun Context.toast(message: String)
Список всех запущенных сервисов
ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE); List rs = am.getRunningServices(50); for (int i = 0; i
Ущемление прав службы
Google последовательно борется с ограничениями для служб, урезая их возможности. Делается это для того, чтобы службы не висели в памяти бесконечно долго и тратили заряд батареи. Ограничение возможностей происходит постепенно от версии к версии. В последних версиях уже можно столкнуться с примерами, когда выкидывается исключение при неправильной работе с службами.
Для решения проблем следует изучить такие вещи как JobScheduler, Firebase Job Dispatcher, WorkManager. Также появилось понятие Foreground service.
Системные службы
Кроме создания собственных сервисов, вы можете использовать системные сервисы. Вот небольшой список:
- Account Service — служба для управления пользовательскими учётными записями
- Activity Service — служба для управления активностями
- Alarm Service — служба для отправки разовых или периодических оповещений в заданное время
- Bluetooth Service — служба для Bluetooth
- Clipboard Service — служба для управления буфером обмена
- Connectivity Service — служба для управления сетевыми соединениями
- Download Service — служба для управления загрузками
- Input Method Service — служба для управления текстовым вводом
- JobScheduler — служба для планирования задач
- Location Service — служба для отслеживания координат
- Layout Inflater Service — служба для управления компоновкой экрана при динамическом создании из кода
- NFC Service — служба для управления NFC
- Notification Service — служба для управления уведомлениями
- Power Service — служба для управления энергопотреблением
- Search Service — служба для управления глобальным поиском
- Sensor Service — служба для доступа к датчикам
- Telephony Service — служба для управления телефонными функциями
- Vibrator Service — служба для доступа к виброзвонку
- Wallpaper Service — служба для управления обоями на домашнем экране
- Wifi Service — служба для управления соединениями Wi-Fi
Сервисы
Сервисы представляют собой особую организацию приложения. В отличие от activity они не требуют наличия визуального интерфейса. Сервисы позволяют выполнять долговременные задачи без вмешательства пользователя.
Все сервисы наследуются от класса Service и проходят следующие этапы жизненного цикла:
- Метод onCreate() : вызывается при создании сервиса
- Метод onStartCommand() : вызывается при получении сервисом команды, отправленной с помощью метода startService()
- Метод onBind() : вызывается при закреплении клиента за сервисом с помощью метода bindService()
- Метод onDestroy() : вызывается при завершении работы сервиса
Создадим простейшее приложение с сервисом. Наш сервис будет воспроизводить музыкальный файл. И вначале добавим в проект в каталог res папку raw . Для этого нажмем правой кнопкой мыши на каталог res и в контекстном меню выберем пункт New -> Android Resource Directory .
Далее укажем в качестве типа папки — raw :
И поместим в эту папку ( res/raw ) какой-нибудь mp3-файл.
Затем добавим новый класс сервиса. Назовем его MediaService . В итоге получится следующий проект:
Для воспроизведения аудио-файла определим в классе MediaService следующий код:
package com.example.soundserviceapp; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; public class MediaService extends Service < MediaPlayer ambientMediaPlayer; @Override public IBinder onBind(Intent intent) < throw new UnsupportedOperationException("Not yet implemented"); >@Override public void onCreate() < ambientMediaPlayer=MediaPlayer.create(this, R.raw.music); ambientMediaPlayer.setLooping(true); >@Override public int onStartCommand(Intent intent, int flags, int startId) < ambientMediaPlayer.start(); return START_STICKY; >@Override public void onDestroy() < ambientMediaPlayer.stop(); >>
Для воспроизведения музыкального файла сервис будет использовать компонент MediaPlayer .
В сервисе переопределяются все четыре метода жизненного цикла. Но по сути метод onBind() не имеет никакой реализации.
В методе onCreate() инициализируется медиа-проигрыватель с помощью музыкального ресурса, который добавлен в папку res/raw.
В методе onStartCommand() начинается воспроизведение.
Метод onStartCommand() может возвращать одно из значений, которое предполагает различное поведение в случае, если процесс сервиса был неожиданно завершен системой:
- START_STICKY : в этом случае сервис снова возвращается в запущенное состояние, как будто если бы снова был бы вызван метод onStartCommand() без передачи в этот метод объекта Intent
- START_REDELIVER_INTENT : в этом случае сервис снова возвращается в запущенное состояние, как будто если бы снова был бы вызван метод onStartCommand() с передачей в этот метод объекта Intent
- START_NOT_STICKY : сервис остается в остановленном положении
Метод onDestroy() завершает воспроизведение.
Чтобы управлять сервисом, изменим activity. Сначала добавим в файл activity_main.xml пару кнопок для управления сервисом:
И изменим код MainActivity :
package com.example.soundserviceapp; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); >public void click(View v) < Intent i=new Intent(this, MediaService.class); if (v.getId()==R.id.start) < startService(i); >else < stopService(i); >> >
Для запуска сервиса используется объект Intent:
Intent i=new Intent(this, MediaService.class);
Для запуска сервиса в классе Activity определен метод startService() , в который передается объект Intent. Этот метод будет посылать команду сервису и вызывать его метод onStartCommand() , а также указывать системе, что сервис должен продолжать работать до тех пор, пока не будет вызван метод stopService().
Метод stopService() также определен к классе Activity и принимает объект Intent. Он останавливает работу сервиса, вызывая его метод onDestroy()
И в конце нам надо зарегистрировать сервис в файле манифеста:
Регистрация сервиса производится в узле application с помощью добавления элемента . В нем определяется атрибут android:name , который хранит название класса сервиса. И кроме того может принимать еще ряд атрибутов:
- android:enabled : если имеет значение «true», то сервис может ли создаваться системой. Значение по умолчанию — «true».
- android:exported : указывает, могут ли компоненты других приложений обращаться к сервису. Если имеет значение «true», то могут, если имеет значение «false», то нет.
- android:icon : значок сервиса, представляет собой ссылку на ресурс drawable
- android:isolatedProcess : если имеет значение true, то сервис может быть запущен как специальный процесс, изолированный от остальной системы.
- android:label : название сервиса, которое отображается пользователю
- android:permission : набор разрешений, которые должно применять приложение для запуска сервиса
- android:process : название процесса, в котором запущен сервис. Как правило, имеет то же название, что и пакет приложения.
Запустим приложение и нажмем на кнопку запуска сервиса:
После этого начнется воспроизведение добавленной нами в приложение мелодии.
Что такое и зачем нужен Service? Какие бывают виды сервисов?
Service – это компонент приложения, который используется для выполнения долгих фоновых операций без взаимодействия с пользователем.
Любой компонент приложения может запустить сервис, который продолжит работу, даже если пользователь перейдет в другое приложение.
Примеры использования сервисов: проигрывание музыки, трекинг локации водителя в приложении такси, загрузка файла из сети.
Сервисы делятся на два вида по способу использования: Started и Bound, и на два вида по способу взаимодействия с пользователем: Background и Foreground.
Когда спрашивают о видах сервисов обычно имеют в виду способ использования.
Started Service Запускается методом startService(Intent intent). Intent должен быть явным (explicit), это значит, что при создании объекта Intent было передано имя класса сервиса.
После запуска сервиса вызывается метод onStartCommand().
Остановить сервис можно вызовом метода stopSelf() из самого сервиса или методом stopService() из другого компонента.
Bound Service привязывается к компоненту вызовом метода bindService(Intent service, ServiceConnection serviceConnection, int flags).
Аргумент serviceConnection используется для взаимодействия с привязанным сервисом. Сервис стартует после вызова bindService() , если аргумент flags имеет значение BIND_AUTO_CREATE.
После вызова bindService() у сервиса вызывается метод onBind().
Для отвязывания компонента от сервиса используется метод unbindService(). У сервиса вызывается метод onUnbind().
Если у сервиса больше нет привязанных компонентов, вызывается метод onDestroy().
Компонент может быть привязан к сервису, запущенному методом startService() . В этом случае сервис относится сразу и к Started и к Bound.
Bound и Started сервисы важно различать, потому что у них разные жизненные циклы.
Мобильные приложения: виды и принципы работы
По данным eMarketer, люди всё больше времени проводят в телефонах, и в ближайшее время тенденция будет только нарастать — по прогнозам, в 2022 году люди будут сидеть в смартфонах по 4 часа в день, и 88% этого времени проведут в приложениях. В статье разбираем типы мобильных приложений, принципы их работы и отличия от веб-сайтов.
Мобильное приложение — это программное обеспечение, которое можно загрузить на смартфон или планшет. Всё началось с простых игр на ещё кнопочных телефонах, но современные продукты могут закрывать почти любые потребности: оплатить налоги, записаться к врачу, найти вакансии по запросу или пару на вечер, заказать еду и забронировать отель.
Если планируете выпустить собственное приложение, мы в AppCraft готовы его разработать и помочь с маркетингом — наша команда больше 10 лет разрабатывает мобильные сервисы и создала более 200 проектов для бизнеса. А пока расскажем, какие бывают приложения и как они работают.
Виды мобильных приложений
По целям бизнеса
Внутреннее пользование
- Сервисы, оптимизирующие работу сотрудников внутри компании: корпоративные социальные сети и мессенджеры, виртуальный офис, облачные хранилища данных и пр.
Как инструмент маркетинга
- Программы лояльности: агрегаторы скидок, системы бонусных карт и кэшбэка для постоянных клиентов.
- Онлайн-сервисы бизнеса: программы для записи к врачу, бронирование туров, отелей и прочее с возможностью проводить банковские транзакции.
В этих случаях приложение используется как инструмент для реализации маркетинговой стратегии — его интерфейс позволяет отправлять пуши и напоминания, побуждающие аудиторию воспользоваться скидкой, купить товар, забронировать жилье или записаться к врачу.
По назначению
Игровые
Задачи на логику, гонки, квесты, викторины, шутеры, детские, взрослые и семейные игры — возможности современной разработки почти безграничны и позволяют создать как простую, так и сложную многоступенчатую систему виртуальной реальности.
Для e-commerce и сферы услуг
Тут собираем всё, что помогает компании охватить как можно больше потенциальной аудитории: программы для заказа такси, записи на приём к косметологу, покупка билетов в кинотеатр и пр.
Контентные
Помогают пользователям быстро получать актуальный контент: новости из изданий и газет, блоги с полезными статьями о психологии, биржи с курсом валют и стоимостью акций, задания по языковым курсам.
Соцсети
Сервисы, которые помогают общаться через смартфон и планшет: ВКонтакте, Instagram, Facebook, Gmail и пр.
По особенностям работы
Нативные
Это проекты, которые созданы под конкретную платформу, написаны на её родном языке и предоставляют все доступные возможности смартфона: камеру, список контактов, GPS, данные о здоровье и режиме сна и т.д. Сервисы под Android чаще всего пишутся на Java, для iOS — Swift или objective-С.
Плюсы: высокая скорость и производительность, возможность реализовать максимальный набор функций, понятный интерфейс, способность работать без интернета, надёжный уровень безопасности, поддержка от маркетплейсов.
Минусы: высокая стоимость и долгий процесс разработки, дорогое техобслуживание.
Мобильные веб-приложения
Его можно назвать сайтом, адаптированным под любой телефон. Веб-сервис можно установить как закладку в браузере и использовать вне зависимости от платформы, не скачивая на телефон и не тратя память.
Плюсы: простой и недорогой процесс создания, не нужно проходить модерацию и публиковаться в каждом маркетплейсе, лёгкий доступ для пользователей.
Минусы: для работы нужно подключение к интернету, ограниченный интерфейс, низкая производительность и скорость, нельзя отправлять push-уведомления.
Кроссплатформенные
Универсальные сервисы, которое создаются сразу под две платформы: iOS и Android и сочетают особенности веб и мобильных приложений.
Плюсы: низкая стоимость и высокая скорость выпуска, кроссплатформенность, автономное обновление.
Минусы: скорость ниже, чем у нативных, некорректная работа в случае плохого интернета, ограниченные возможности визуала.
Как работают мобильные приложения
Чем отличаются от веб-сайтов
Мобильные сервисы сложнее и дороже создавать, но позволяют качественное взаимодействовать с пользователями — затраты на них быстро окупаются и помогают формировать лояльную аудиторию.
- Уведомления. Через приложение можно отправлять push-уведомления и напоминания, даже если человек не открывает сервис, выполнять функции в фоновом режиме и без подключения к интернету.
- Оперативная обратная связь с компанией через чат и техподдержку.
- Индивидуальный сервис. Есть возможность использовать геолокацию, биологический ритм человека, данные об интересах и запросах в поисковиках, чтобы предложить индивидуальный сервис: вызвать машину к дому, создать рацион питания и режим тренировок, предложить необходимые анализы с учётом истории болезней или подобрать подходящую пару по интересам.
- Удобнее пользоваться: интерфейс приложения адаптирован под действия пользователей и имеет понятную структуру с кнопками.
- Подробная аналитика. С помощью статистики в приложении можно анализировать поведение целевой аудитории, составлять более подробный портрет клиента и подбирать эффективные маркетинговые стратегии.
Архитектура
Тут есть два основных блока: фронтенд и бэкенд-части. Они действуют как сплит-система и взаимодействуют друг с другом, передавая информацию и обеспечивая бесперебойную работу продукта.
Back-end часть не видна пользователям, но именно на ней держится вся логика сайта, обрабатываются данные и отправляются реакции. Бэкенд-разработчики обеспечивают корректное функционирование интерфейса, заставляют каждую кнопку переносить человека на нужную страницу, совершать оплату через банковские системы и собирать данные.
Front-end обеспечивает внешний вид интерфейса, с которым взаимодействуют пользователи. Это дизайн страниц, кнопок, пуш-уведомлений и других графических элементов, карта путешествия пользователя и взаимодействие с функциями.
На каких языках программирования создаются
Java
На нем написаны большинство Android-приложений в Google Play Market.
Java используют для разработки под Android, кроссплатформенных и гибридных интерфейсов, но в последних двух случаях нужно будет задействовать и другие языки, чтобы учесть специфику каждой операционной системы.
Kotlin
Был создан для преодоления недочетов Java и используется для написания кода почти всех новых сервисов на Android.
Objective С
Его начали использовать в 80-х годах 20 века. Он был создан на основе C и Smalltalk, а в 2008 году Apple выпустил iPhone SDK 2.0, позволяющий создавать программы для iOS. Сначала его считали надстройкой к С, но, когда лицензировали NextStep и Apple, Objective С стал официальным языком всех интерфейсов под iOS.
Swift
Swift не только перенял все плюсы Objective С, но и был наделен новыми функциями, которые упрощают написание и реализацию кода.
Rust
Rust начал создаваться в 2006 году разработчиком Грейдоном Хором, который хотел соединить в нем скорость C++ и надежность Haskell. В 2009-ом к нему присоединилась Mozilla, и год спустя его презентовали на Mozilla Summit. Сейчас Rust является одним из самых популярных среди разработчиков. Используется для создания нативных и веб-приложений на Android, iOS, Linux, Windows и Unix.
С#
Раньше использовался в основном для Windows Mobile, но в последнее время C# научился работать на Mac, Linux, IoS и Android. За счет удобного синтаксиса, строгого структурирования и большого количества библиотек и инструментов на нем можно писать разные виды интерфейсов и решать любые задачи с меньшими затратами времени и ресурсов.
В каких случаях необходимы бизнесу
Если пользователи чаще пользуются телефоном, чем компьютером. Отследить статистику можно через «Яндекс.Метрику» или Google Analytics. Если больше 50% клиентов заходят на ваш сайт через смартфон, это знак к действию: предоставьте пользователям удобные условия для заказа, пока этого не сделали конкуренты.
Есть система лояльности. Замените пластиковые карты и бумажные купоны с наклейками удобным онлайн-сервисом (идеально, если он будет работать даже без интернета). Предложите покупателям электронную бонусную карту с баллами, скидку за скачивание приложения и удобный личный кабинет для отслеживания активности.
Конкуренты уже используют приложение. Если на рынке уже начали использовать мобильные технологии, ждать точно не стоит. Изучите предложения других компаний, придумайте дополнительные функции для собственного продукта и начинайте разработку, чтобы не потерять клиентов.
Нужны новые инструменты для продаж. Сервис позволяет реализовывать маркетинговые акции: проводить розыгрыши и акции, рассказывать о новых продуктах и услугах, напоминать о записи и предлагать индивидуальные условия для каждого человека.
Создание приложений — сложный процесс, но в руках опытной команды всё создаётся быстро без потери качества и на каждом этапе тестируется на реальной целевой аудитории.
Команда AppCraft занимается всеми этапами разработки: от аналитики до релиза, обеспечивает оперативную доработку кода и техподдержку.
За 10 лет работы мы создали несколько собственных проектов и больше 200 приложений — мессенджеры, корпоративные соцсети, системы для банковских продуктов и интернет-магазины. Если вы хотите создать собственное мобильное приложение для бизнеса, мы готовы превратить вашу идею в функциональный и популярный продукт.
Свяжитесь с нами через форму, чтобы обсудить подробности и узнать точную цену.
Технологии
Разработка мобильных приложений для медицинских центров, медклиник
По результатам исследования Ricoh Research,79% пациентов отдают предпочтение клиникам с удобными сайтами и приложениями — они вызывают доверие и помогают сократить время на запись к врачам и заполнение документов. В статье мы описали особенности и шаги разработки приложений в сфере медицины опираясь на наш десятилетний опыт разработки.
Тоже интересно
PWA приложения и с чем их едят
В этой статье мы попробуем разобраться в ключевых аспектах разработки приложений PWA и изучим их преимущества, особенности и перспективы на будущее.
Как улучшить показатель удержания аудитории в EdTech проектах?
Все сервисы предоставления онлайн услуг в определенный момент сталкиваются с одной общей проблемой — удержание клиента. Привлечение в сервис нового клиента почти всегда стоит дороже, чем прибыль от его первой покупки, и способы удержания становятся основной головной болью для любого бизнеса. В данной статье мы рассмотрим, как мобильное приложение может помочь повысить retention rate и создать дополнительный канал привлечения клиентов на примере отрасли EdTech.
Стоимость разработки мобильного приложения для iOS и Android на заказ в 2023 году
В вопросе определения стоимости разработки мобильного приложения не так сложно разобраться, достаточно подойти к нему вдумчиво и системно.
Импортозамещение ПО и мобильные приложения: что разрабатывать?
Высокий уровень цифровизации имеет только 11% бизнеса — и это исследование проводилось уже после начала пандемии, которая простимулировала диджитализацию. По мере того, как с российского рынка стали уходить зарубежные IT-продукты, спрос на отечественное ПО возрос на 300%. Какие проекты стоит запускать в текущих условиях? В каких нишах требуются мобильные приложения? Размышляем в статье.
Контакты
8(499)348-82-16
- 107140, Москва,
ул. Русаковская, 1, оф. 306 - 390042, Рязань,
ул. К.Маркса, 3, к.2
Компания
Написать нам
Соцсети
Copyright © 2011-2022, AppCraft LLC
Мы используем куки, чтобы
сделать мир прекраснее
Спасибо!
Мы скоро с вами свяжемся и подробно проконсультируем по интересующим вас вопросам.
А пока можете узнать подробнее о том, как формируется стоимость, сколько времени занимает реализация проекта и о других нюансах разработки в наших статьях.
Сроки разработки мобильного приложения
Стоимость разработки мобильного приложения