- Android studio android exported
- Как экспортировать проект Android Studio?
- Сервисы Android: начало работы
- Сервисы Android: начало работы
- Давайте начнем
- Представляем Android Services
- Объявление сервиса в Manifest
- Реализация интерфейса сервиса
- Создание сервиса Foreground
- Применение методов сервиса.
- Добавление разрешений
- Создание канала уведомлений
- Создание конструктора уведомлений
- Заметка
- Создание самого уведомления
- Запуск и остановка службы
- Обновление уведомления при изменении таймера
- Использование фоновой обработки для сложных задач
- Объяснение ограничений для фонового выполнения
- Заметка
- Создание Bound Service
- Преобразование MusicService в реальный Service
- Определение Binder
- Определение методов сервисов для управления аудио
- Создание колбэка для подключения к службе
- Использование методов сервисов
- Межпроцессные взаимодействия
- Что дальше?
Android studio android exported
Всем приветы! Прежде чем знакомить вас с данной инструкцией, сразу признаюсь что сам туго представляю как всё работает и не знаю всех нюансов, но, тем не менее, опытным путём, не затратив много времени проделал экспорт и делюсь с вами опытом, скорее не для того чтобы научить, а больше порадовать что в Construct 3 с экспортом всё легко и просто=)
Короче эта статья фуфло и не оформлена должным образом, скорее это заметка/шпаргалка, и если кто либо удосужиться создать материал получше моего я с облегчением удалил бы эту тему либо улучшил.
Этапы экспорта:
A. Экспорт проекта в формат Android studio project
B. Импорт проекта в Android studio project и создание ключа
A. Экспорт проекта в формат Android studio project
1. Открываем наш проект в С3, далее в главном меню запускаем Export
Menu->Project->Export
2. В открывшемся окне выбираем Android(Cordova)
3. В окне Export options нам доступны сразу три опции. Задействовать их или нет, решать вам, нужны они для следующего:
— Deduplicate images — разыскивает в вашем проекте идентичные картинки и оставляет в еденичном экземпляре, на функционале проекта это никак не скажется, просто движок сам впихнёт картинку где надо. Соответственно это уменьшит размер самого APK файла. Насколько это корректно работает мне не известно, но проблем от использования этой функции я пока не обнаружил.
— Recompress images — пережимает и оптимизирует все спрайты в проекте, экономя опять же вам килобайты в АРК. Не представляю как это именно работает и что даёт по файлу, ибо на момент написания этой заметки экспорт крашится при задействовании этой функции. Так что, не стоит=)
— Minify script — делает код проекта более компактным для ускорения его работы. И вроде как усложняет при этом декомпиляцию. Если честно, у меня были проблемы при экспорте из за этой функции в С2, но уже в С3 их не возникло.
Когда определитесь с выбором жмите Next .
4. В окне Cordovs options мы видим:
— Android versions — минимальная версия андройд для вашего проекта.
— Android build — выбираем строго Android studio project. Вы можете заметить что в экспорте доступны сразу Debug APK/Release APK, и это вам создаст АРК сразу, но они не будут подписаны и без отключения проверки подписи вы вряд ли сможете их установить. Прошу меня простить, я не стал тратить время на изучение этой опции, мне не удобно рассылать такие АРК друзьям и я не в курсе как их подписать. Если знаете — пишите как=) Тогда в этой теме совсем не будет необходимости, такие страдания, чего ради?=))
— Hide status bar — даёт возможность вкл/выкл полоску статуса андройда, это та полоска с часами, зарядом батареи и прочими уведомлениями.
— Require Vibrate/Camera permission — запросы на использование вибрации и камеры в вашем проекте, если вы добавили это в него.
После выбора опций опять жмите Next .
С3 начнёт обрабатывать ваш проект, и здесь вам понадобится подключение к интернету, ибо эти процессы работают через онлайн сервис C3.
5. По завершении обработки, в центре экрана вы увидите следующее окно:
Жмите Download (имя_вашего_проекта.android.project.zip)
Либо можете сделать тоже самое в Project manager. Это неплохой вариант и он имеет доп. функции но моя заметка не о нём.
Архив с проектом скачается в вашу папку для закачек по умолчанию, советую его оттуда переместить в более удобное место чтобы не путаться, да хотя бы на рабочий стол.
Сразу распакуйте его.
B. Импорт проекта в Android studio project и создание ключа
1. При первом запуске Android studio project, вам покажут следующее окно:
Укажите куда сохранить АРК файл и можете выбрать тип релиза Gebug или Release.
Спасибо за внимание. Надеюсь помог.
К сожалению актуальность и годноту содержания гарантировать не могу. По возможности конечно с радостью улучшу и расширю информацию если будет чем.
Источник
Как экспортировать проект Android Studio?
Я только начал использовать Android Studio IDE, и я уже выпустил и опубликовал простой APK в магазине Google Play. Проблема в том, что я сделал это на работе. Теперь я загрузил Android Studio в свой дом, и я хочу продолжить работу и исправлять ошибки в моем проекте. Я вижу, что есть Import Project на главном экране Android Studio, но откуда я экспортирую проект, чтобы импортировать его? Я попробовал Zipping всю папку Project и импортировал его, но он не работал очень хорошо.
В Android Studio перейдите в « File затем « Close Project . Затем возьмите папку (в папке рабочего пространства) проекта и скопируйте ее во флэш-память или что угодно. Затем, когда вам станет комфортно дома, скопируйте эту папку в папку рабочей области, которую вы уже создали, откройте Android Studio и перейдите в « File затем « Open и импортируйте этот проект в рабочее пространство.
Проблема с этим заключается в том, что вы ищете неправильный термин здесь, потому что в Android экспорт проекта означает его компиляцию в файл .apk (не экспортируя проект). Импорт / экспорт используется для управления .apk , вам нужен проект Open / Close, другая вещь – просто копировать / вставлять.
Как уже упоминалось в других ответах, на данный момент андроид-студия не предоставляет этого из коробки. Однако есть способы сделать это легко.
Как упомянуто @Elad Lavi, вы должны рассмотреть облачный хостинг вашего исходного кода. Checkout github, bitbucket, gitlab и т. Д. Все это предоставляет частные репозитории, некоторые бесплатные, некоторые нет.
Если все, что вам нужно, это просто заархивировать источники, вы можете добиться этого, используя git- git archive . Вот шаги:
Примечание. Если вы собираетесь отправить это по электронной почте, вам нужно удалить gradlew.bat из zip-файла.
Оба этих решения возможны благодаря VCS, как git.
Кажется, что в Android Studio отсутствуют некоторые функции, которые имеет Eclipse (что удивительно, учитывая выбор, чтобы сделать официальную IDE для Android Studio).
Eclipse имел возможность экспортировать zip-файлы, которые можно было бы отправить по электронной почте, например. Если вы заархивируете папку из своей рабочей области и попытаетесь отправить ее через Gmail, например, Gmail откажется, поскольку папка содержит исполняемый файл. Очевидно, вы можете удалять файлы, но это неэффективно, если вы делаете это часто, возвращаясь с работы.
Вот решение: вы можете использовать контроль источника. Android Studio поддерживает это. Ваш код будет сохранен в Интернете. Гит сделает трюк. Посмотрите под «VCS» в верхнем меню в Android Studio. Он также имеет много других преимуществ. Один из недостатков заключается в том, что если вы используете GitHub бесплатно, ваш код будет открытым исходным кодом, и каждый сможет его увидеть.
Контроль источника – лучший способ справиться с этой проблемой, если вы не хотите платить, тогда попробуйте bitbucket
Это бесплатно, позволяет частное репо для группы из 5 человек.
Окна:
Сначала откройте окно команд и установите местоположение вашей папки проекта студии Android так:
Затем введите в нем команду ниже:
Затем дождитесь полного процесса очистки. После завершения его теперь застегните свой проект, как показано ниже:
- Щелкните правой кнопкой мыши на папке проекта
- Затем выберите « Отправить»
- Выбрать сжатый с помощью zip
По-видимому, в «сборках» каталогов проекта есть много «мертвой древесины».
В linux / unix простой способ получить чистую приватную резервную копию – использовать команду «tar» вместе с опцией «–exclude = String».
Например, чтобы создать архив всех моих приложений, исключая каталоги сборки, у меня есть скрипт, который создает следующие 2 команды:
Источник
Сервисы Android: начало работы
Сервисы Android: начало работы
Многие приложения Android имеют функции, выполнение которых требует много времени, например загрузка какого-либо контента или обновление удаленной базы данных. Если разработчики не организуют работу подобных функций должным образом, они постепенно загромоздят основной поток, создав утечки памяти и неточности в работе. Это может сильно раздражать ваших пользователей.
К счастью есть Android Services, которые позволяет сделать работу с подобным функционалом. Android Services — это особый тип компонента приложения, который предназначен для обработки повторяющихся и/или длительно выполняемых процессов.
- В этом туториале вы узнаете:
- Что такое Android Services и как их объявить в файле Manifest.
- Как использовать foreground сервис для отображении уведомления пользователю.
- Что такое фоновая обработка сложных процессов, не связанных с пользовательским интерфейсом.
- Как использовать bound service.
Давайте начнем
В этом туториале вы будете использовать приложение Memo. Memo — это игра, в которой пользователю предлагается сопоставить карты за как можно меньшее время. Кроме того, пользователь может прослушивать разные саундтреки во время игры .
В игре четыре уровня сложности: Beginner (Начальный), Intermediate (Средний), Advanced (Продвинутый ) и Expert (Эксперт). Чем выше уровень сложности, тем больше карт нужно сопоставить. После того, как пользователь выполняет задание на уровень эксперт, он проходит игру. Не хотите попробовать? :]
В настоящее время приложение позволяет пользователю только запускать игру и управлять саундтреками. Запустив игру, вы сможете выйти из нее, просмотреть игровые карточки и засечь время, прошедшее с момента запуска игры.
Откройте проект в Android Studio и ознакомьтесь с файлами. Когда вы закончите, запустите проект на устройстве / эмуляторе, чтобы посмотреть, как он выглядит.
Вы можете поиграть в игру, нажав на кнопку PLAY BEGINNER LEVEL. Сейчас вы уже можете сопоставлять карточки, однако отсутствует таймер, отображающий количество времени, затраченное на решение задачи. Это первое, что мы реализуем в этом туториале.
Однако сначала давайте более подробно рассмотрим, что такое Android Services и как их использовать.
Представляем Android Services
Android Services — это компонент, который помогает выполнять длительные процессы, такие как обновление базы данных или сервера, запуск обратного отсчета или воспроизведение звука. По умолчанию Android Services запускаются в том же потоке, что и основные процессы приложения. Такой вид службы также называют local service.
Ресурсоемкие задачи данный сервис будет выполнять в фоновом режиме. Это позволит пользователю взаимодействовать с приложением. Например, если пользователь захочет позвонить или просмотреть уведомления при обновлении сервера, он сможет сделать это, не прерывая и не отменяя обновления.
Для этого нужно создать фоновый поток и вручную указать, какие задачи должны выполняться именно в этом потоке, поскольку сервисы не поддерживают реализацию потока напрямую.
Поскольку Android Services не имеет пользовательского интерфейса, он никак не зависит от последовательности выполнения других процессов. Это означает, что вы можете запускать его, даже когда пользователь вообще никак не взаимодействует с приложением.
Кроме того, другие компоненты приложения могут взаимодействовать с сервисами или даже осуществлять межпроцессное взаимодействие (InterProcess Communication (IPC)). Если вы будете дальше следовать этому туториалу, то узнаете больше о IPC.
В следующих разделах этого туториала мы применим каждый из перечисленных ниже типов Android Services и добавим в наше приложение Memo много новых функций:
- Foreground service: Добавим сервис TimerService, который содержит логику для отслеживания времени.
- Bound service: Используем MusicService, который позволит нам воспроизводить, ставить на паузу и перемешивать саундтреки.
Объявление сервиса в Manifest
Перед использованием сервиса его необходимо объявить в AndroidManifest.xml. Сервис — это компонент Android, точно так же, как и Activity. Для удобства наш проект уже содержит классы сервисов, но вам все еще необходимо правильно их конфигурировать.
Перейдите к AndroidManifest.xml и добавьте этот код внутрь application :
В этом кода вы можете увидеть следующее:
- Android:name: Имя класса сервиса.
- Android:enabled: Если установлено значение true, система может создавать экземпляры сервисов.
- Android:exported: Если установлено значение False, то системе сообщается, что ни одно другое приложение не может запускать и использовать эти сервисы.
Значение android:name выделиться красным цветом, но пока просто не обращайте на это внимание. Мы починим это чуть позже.
А пока начнем работу по реализации нового функционала.
Реализация интерфейса сервиса
Каждый кастомный класс сервиса должен быть подклассом Service и должен реализовывать и переопределять несколько базовых методов колбэка, связанных с жизненным циклом сервиса.
Вот наиболее важные из них:
- onStartCommand(): вызывается системой, когда другой компонент хочет запустить сервис, использую startService() . Как только система вызывает onStartCommand() , сервис может работать в фоновом режиме столько времени, сколько потребуется для завершения процесса. Вам нужно не забыть остановить службу вручную, когда работа будет завершена, вызвав stopSelf() или topService() . Эта не нужно, если вы хотите просто выполнить привязку к сервису, не запуская его.
- onBind(): Вам всегда нужно применять этот метод колбэка. Система использует этот колбэк при вызове bindService() . Используйте его для привязки другого компонента к сервису. Он открывает возможность коммуникации, таким образом вы предоставляете интерфейс для взаимодействия клиентов возвращая IBinder . Если вы не хотите использовать привязку, просто верните null .
- onCreate(): Используйте этот метод для настройки сервиса перед его запуском. Система вызывает его, только если сервис еще не запущен.
- onDestroy(): Система вызывает его, чтобы уничтожить сервис, когда он больше не нужен. Это последний вызов, который получает сервис. После этого сервис перестает использовать какие-либо ресурсы.
Создание сервиса Foreground
Сервис Foreground выполняет задачи, которые необходимо видеть пользователю. Он выводит уведомления в строку состояния, чтобы сообщить пользователю о том, что приложение выполняет операцию и потребляет ресурсы. Уведомление должно иметь приоритет PRIORITY_LOW или выше и быть видимым, даже если пользователь не взаимодействует с приложением.
Пользователь не может закрыть уведомление. Оно исчезает, когда служба завершает свою работу или покидает передний план.
Чтобы увидеть работу данного сервиса в действии давайте реализуем TimerService . Откройте TimerService.kt и добавьте следующее, чтобы сделать его подклассом Service :
В этой строчке мы применяем интерфейс Service и CoroutineScope .
Применение методов сервиса.
Присмотритесь и обратите внимание, что Android Studio выдает ошибку из-за того, что не может найти onBind() .
Чтобы исправить это добавьте следующее в TimerService :
Давайте разберем этот код немного подробнее:
- Так как мы используем сервис переднего плана, нам не нужно выполнять привязку и мы возвращаем null вместо IBinder . Также заметьте, что мы не используем onCreate() , так как нам не нужна никакая специфическая конфигурация для этого сервиса.
- Здесь мы просматриваем дополнительные возможности Intent , чтобы получить значение, которое содержит ключ SERVICE_COMMAND . Это значение указывает на то, какое действие должен выполнить сервис.
- Если система завершает работу сервиса из-за нехватки памяти, START_NOT_STICKY говорит системе о том, что не стоит создавать службу с неопределенным Intent . Альтернативные константы: START_STICKY и START_REDELIVER_INTENT . Если вас интересует функционал этих констант, ознакомьтесь с официальной документацией по константам сервисов.
- Временно удалите все колбэки Handler , чтобы не засорять память. Кроме того, стоит очистить ресурсы, отменив все Job таймера, поскольку на следующем шаге сервис будет уже уничтожен.
Добавление разрешений
Все приложения, созданные для Android 9 (уровень API 28) или выше, должны запрашивать разрешение на использование службы переднего плана. Система автоматически разрешит доступ к сервису. В противном случае приложение генерирует исключение SecurityException.
В Project view перейдите к app ▸ manifest ▸ AndroidManifest.xml и добавьте следующий код над тегом application :
Это позволит нашему приложению Memo использовать сервис переднего плана.
Далее давайте создадим уведомление, которое будет говорить о работе этого сервиса.
Создание канала уведомлений
Любой сервис переднего плана должен уведомлять пользователя о своем запуске. Вам также необходимо определить диспетчер уведомлений, который уведомляет пользователя о происходящих событиях и содержит информацию об одном или нескольких уведомлениях.
Откройте NotificationHelper.kt и добавьте этот код в начало класса:
Здесь вам не нужно инициализировать notificationManager , получив системную службу NOTIFICATION_SERVICE и преобразовав ее в NotificationManager .
В Android 8 и более поздних версиях уведомление должно быть частью канала уведомлений. Чтобы создать его, добавьте этот код в NotificationHelper.kt:
В этом кусочке кода мы:
- Создаем канал уведомлений с CHANNEL_ID в качестве идентификатора, CHANNEL_NAME в качестве имени и дефолтным приоритетом по умолчанию.
- Устанавливаем значение CHANNEL_DESCRIPTION для описания канала уведомлений, а для звука — значение null , что означает, что при срабатывании уведомления в канале звук не будет воспроизводиться.
Следующим шагом будет работа с отображением уведомлений.
Создание конструктора уведомлений
Чтобы пользователь знал о запущенном сервисе, создайте уведомление, которое пользователь сможет увидеть в строке состояния. Вверху NotificationHelper.kt добавьте:
Если вы получаете ошибку, сообщающую, contentIntent не определено, не волнуйтесь. Мы позаботимся об этом на следующих шагах.
В этом коде мы реализовали следующее:
- Мы использовали NotificationCompat.Builder для того, чтобы создать конструктор уведомлений, отображаемых в строке состояния.
- Конструктор должен содержать информацию о некоторых параметрах уведомления. Однако вам не нужно определять эти параметры при объявлении конструктора. Если не будет хватать какой-либо информации, мы всегда сможем указать эту информацию в самом уведомлении.
- Этот тип уведомления должен быть настроен как автоматически отменяемый. Это означает, что когда пользователь нажмет на уведомление, оно автоматически закроется.
Заметка
Многие разработчики допускают очень глупую ошибку. Они забывают присвоить уведомлению небольшой значок (иконку). Это приводит к тому, что уведомление получается невидимым.
Создание самого уведомления
Пришло время создать само уведомление. Добавьте в NotificationHelper.kt следующее:
Вот что происходит в этом куске кода:
- Если версия Android равна 8 или выше, система создает канал уведомления и возвращает Notification . К сожалению, библиотека поддержки для версий до Android 8 не предоставляет API каналов уведомлений. Подробнее об этой проблеме читайте в официальной документации на тему каналов уведомлений.
- Возвращается Notification после вызова build() в конструкторе.
Уведомление может обновляться динамически. В этом случае мы будем обновлять текст, если пользователь закроет приложение во время работы службы.
Ниже getNotification() добавьте следующее:
Вот, что здесь происходит:
- Мы обновляем текст в уведомлении, отображаемом в строке состояния, через notificationBuilder .
- Затем говорим диспетчер уведомлений какое уведомление нужно обновить. Для этого мы используем уникальный NOTIFICATION_ID .
Наконец, давайте определим, что происходит, когда пользователь нажимает на уведомление. Добавьте это в начало NotificationHelper.kt:
Здесь вы выполняете ленивую инициализацию PendingIntent , которая запускает MainActivity , когда пользователь нажимает на уведомление.
Прекрасная работа! Уже очень многое было реализовано. Теперь пора запустить Foreground Service.
Запуск и остановка службы
Чтобы запустить Foreground Service, используйте startForeground() . Для этого метода требуются два параметра: уникальный положительный целочисленный идентификатор уведомления и Notificaton .
Откройте TimerService.kt и добавьте следующее в метод startTimer() :
Этот метод заставляет службу работать на переднем плане и отправляет уведомление с идентификатором NOTIFICATION_ID в строку состояния. Вы заметите, что helper выделен красным, потому что вы еще не определили переменную helper .
Чтобы исправить это создайте экземпляр класса NotificationHelper в верхней части TimerService :
Чтобы попытаться запустить сервис из другого компонента, откройте MainActivity.kt, найдите sendCommandToForegroundService() и добавьте:
Здесь мы запускаем сервис из Activity. Вы передаете его Context и Intent для запуска сервиса.
Все, что начинается, должно заканчиваться, в том числе и сервисы. Откройте TimerService.kt и добавьте в stopService() следующее:
В этом блоке кода:
- Этот вызов сообщает системе, что она должна убрать этот сервис из foreground. Переданный логический аргумент соответствует удалению уведомления, если для него установлено значение true .
- Поскольку сервис может запускаться сам, он также должен и завершаться сам. stopSelf() позволяет это реализовать.
Обновление уведомления при изменении таймера
TimerService содержит сопрограмму, которая тикает каждую секунду во время выполнения уровня. Вы будете использовать значение таймера, чтобы обновить представление уведомлений.
Найдите BroadUpdate () внутри TimerService.kt и добавьте этот код в if :
Вот что делает этот блок кода:
- Здесь вы отправляете трансляцию с истекшим временем в MainActivity . С его помощью MainActivity может обновлять время в TextView .
- Этот вспомогательный метод обновляет уведомление в строке состояния, которое мы сделали ранее.
На этом этапе мы уже сделали все, что видит пользователь во время игры. Но что произойдет, если пользователь закроет приложение во время работы таймера?
Чтобы это работало корректно, добавьте следующую строку в broadcastUpdate() в else if :
Эта строчка обновляет текст уведомления, зазывающего пользователя обратно в игру.
Отличная работа! Запустите проект, чтобы проверить таймер. Запустите игру на каком-нибудь уровне сложности и обратите внимание, как внизу меняется таймер. Потяните вниз строку состояния, чтобы увидеть, как таймер изменяется в уведомлении. Попробуйте выйти из приложения, чтобы проверить обновление текста сообщения в уведомлении.
Использование фоновой обработки для сложных задач
Иногда пользователю не нужно знать о том, что происходит какое-то действие, например, если вы сохраняете данные об активности пользователя на сервере в целях доработки своего приложения, вам не нужно, чтобы пользователь видел уведомление. Поместите такие непрерывные задачи в фоновую очередь.
Для этого вы можете использовать:
- Пользовательский Background Service — по умолчанию сервис запускается в потоке пользовательского интерфейса. Чтобы избежать блокировки, создайте Сервис с обработкой процесса в фоновом потоке.
- IntentService — подкласс сервиса, который последовательно выполняет запросы с помощью рабочего потока. Начиная с Android 8, использовать его не рекомендуется. Кроме того, IntentService устарел с Android 11.
- JobIntentService — замена IntentService. Вместо сервиса он использует JobScheduler для выполнения заданий. В более ранних версиях, чем Android 8, он будет действовать так же, как IntentService. Для получения дополнительной информации прочтите официальную документацию JobIntentService.
- Фоновая работа с WorkManager — это общая концепция фоновой работы в Android. Используйте его, когда вы захотите выполнять периодические процессы в будущем или когда у вас есть некоторые ограничения в работе приложения.
Объяснение ограничений для фонового выполнения
Android 8 и более новые версии имеют ограничения при использовании Android Services в фоновом потоке:
- Система уничтожит сервис через некоторое время, если приложение запускает его в фоновом режиме. Когда приложение переходит в фоновый режим, у него есть всего лишь несколько минут, в течение которого оно может взаимодействовать с сервисами. После этого система останавливает работу всех запущенных служб.
- Система выдаст исключение, если сервис был запущен, когда приложение находилось в фоновом режиме и за пределами временного окна.
Дополнительные сведения см. В документации по ограничениям фонового выполнения.
Заметка
Из-за всех этих ограничений фоновые сервисы используются крайне редко. Как упоминалось выше, а также рекомендовано официальной документацией Android, лучшим решением для фоновой работы является использование Work Manager. Подробнее об этом читайте в разделе «Планирование задач с помощью Android WorkManager».
А теперь пора узнать о последнем виде сервисов.
Создание Bound Service
Bound Service — это все еще применение Service . Это компонент, с которым связываются другие компоненты, взаимодействуют с ним и осуществляют межпроцессное взаимодействие (IPC). Связанный компонент может быть Activity, другим сервисом, приемником трансляции или поставщиком контента.
Жизненный цикл связанного сервиса зависит от другого компонента приложения. Когда компонент отключается, привязанный сервис уничтожает себя. Следовательно, он не может работать в фоновом режиме вечно.
Однако ему не обязательно нужен связанный компонент — он также может запускаться и останавливаться. В этом случае есть возможность работать бесконечно.
Чтобы попробовать это, давайте добавим в Memo возможность воспроизводить звук.
Преобразование MusicService в реальный Service
Для реализации функции воспроизведения звука, давайте воспользуемся MusicService . Во-первых, измените его, чтобы получить доступ к основным методам сервиса.
Откройте MusicService.kt и расширьте его Service :
Как указано в его типе, другой компонент привяжется к этому сервису. Вы уже узнали об обязательном методе привязки к сервису, поэтому добавьте его в MusicService :
Разница между последним применением onBind() и этой строчкой, очевидно, заключается в возвращаемом значении. Поскольку здесь вы привязываетесь к сервису, вам необходимо указать значение IBinder.
IBinder — это программный интерфейс Binder, который клиент использует для взаимодействия с сервисом. Его методы позволяют отправлять вызов объекту IBinder и получать вызов, поступающий в объект Binder. Чтобы узнать больше, ознакомьтесь с документацией IBinder.
Сейчас Android Studio выдает ошибку, потому что мы не определили переменную binder . Чтобы исправить это, добавьте в начало класса следующее:
Здесь мы выполняем отложенную инициализацию binder , который является разновидностью MusicBinder . Внедрение MusicBinder — ваш следующий шаг.
Определение Binder
К этому сервису нельзя получить доступ за пределами этого приложения, и у него нет собственного процесса. Следовательно, нам необходимо создать интерфейс, который будет иметь доступ к контексту сервиса. Сделаем это, расширив класс Binder . Таким образом, все компоненты могут использовать все общедоступные методы из Binder или Service .
Теперь, чтобы определить интерфейс, добавьте эти строки внизу класса:
MusicBinder вложен в другой класс и может получить доступ ко всем его методам. Он также может использовать все методы Binder . Внутри него вы создаете метод для получения контекста сервиса.
Определение методов сервисов для управления аудио
Этот сервис позволяет пользователю взаимодействовать со звуковыми иконками для воспроизведения, приостановки, остановки и перемешивания музыки. Для простоты, некоторые методы управления звуком уже определены. Однако сам музыкальный проигрыватель все еще не определен.
Чтобы создать музыкальный проигрыватель, добавьте этот код в initializeMediaPlayer() внутри MusicService.kt:
Здесь вы используете MediaPlayer для запуска непрерывно повторяющегося звука первой песни в randomSongs .
Еще одна интересная особенность такого сервиса заключается в том, что он может предоставить имя воспроизводимого трека. Внутри MusicService добавьте:
В этом методе мы читаем название дорожки из ресурсов и изменяем String , чтобы она была более читаемой для пользователя.
Все сделано! Теперь воспользуемся этими методами из другого компонента.
Создание колбэка для подключения к службе
Чтобы использовать MusicService внутри других классов, нам нужно создать его экземпляр. Откройте MainActivity.kt и добавьте в начало класса следующее:
Здесь мы объявляем переменную, которая содержит экземпляр сервиса. В данный момент сервис является null . Мы назначим новое значение, когда активити подключится к службе с помощью интерфейса Binder . Чтобы уловить изменения состояния соединения, создайте колбэк соединения.
Добавьте код под инициализацией musicService :
Этот блок кода не сложно понять:
- Это колбэк для состояния подключения сервиса.
- Когда активити подключается к сервису, система использует экземпляр MusicBinder и getService() чтобы передать ссылку в musicService .
- Когда сервис отключается, воспроизведение звука прекратится, если ссылка на сервис еще не приняла значение null , при этом ссылка на сервис будет удалена.
Также устанавливается флаг isMusicServiceBound , который проверяет состояние привязки к сервису в обоих методах в соответствии с заданными вами параметрами. Это важно, чтобы избежать исключений DeadObjectException, которые удаленные методы генерируют при разрыве соединения.
Привязка к Сервису
Следующим шагом мы создадим привязку сервиса при запуске MainActivity . Найдите onStart() и добавьте:
Здесь вы проверяете, имеет ли сервис уже привязку. Если нет, вы вызываете метод привязки.
Метод привязки еще не существует, поэтому добавьте его код ниже onDestroy() :
В этом куске кода мы:
- Заявляем о намерении запустить MusicService
- Предоставляем сервису информацию о нашем Intent вместе с колбэком соединения и флагом, который автоматически создает сервис, если привязка существует.
Чтобы избежать утечек памяти или ошибок, вам нужно добавить код для отмены привязки сервиса. Добавьте в unbindMusicService() следующее:
Таким образом, вы говорите сервису выполнить onServiceDisconnected() в колбеке boundServiceConnection .
Использование методов сервисов
Как только сервис отключится, нам нужно остановить воспроизведение музыки. Добавьте следующий код над только что добавленной строкой unbindService() :
Здесь мы используем экземпляр сервиса, чтобы остановить воспроизведение звука. Помните, что мы не могли вызывать методы из TimerService . Затем нам нужно было предоставить флаги через Intent . Однако здесь у нас есть соединение — привязка — к сервису, поэтому вы можете вызывать его методы и получать ответ.
Чтобы запустить звук, используем sendCommandToBoundService() . Теперь создадим общий вызов к изменению действия, чтобы уменьшить количество строк кода. Добавьте эту строку в sendCommandToBoundService() :
Таким образом, вы задаете сервису действие, которое он выполняет в соответствии с параметром sendCommandToBoundService() .
Осталось сделать еще кое- что! Как только саундтрек начнет воспроизводиться, сервис может предоставить информацию о названии песни. Перед тем, как это применить это в нашем приложении, нужно исправить момент с получением результата.
Внутри getNameOfSong() , замените строку, возвращающую текст «Unknown», на:
Здесь мы вызываем метод сервиса, который проверяет, какая звуковая дорожка в настоящее время воспроизводится, и возвращает необязательный результат String . Если результат равен null , вместо информации, полученной от сервиса, мы используем текст, взятый из ресурсов.
Запустите проект, затем нажмите значок «Play», чтобы запустить воспроизведение. Нажмите GET SONG NAME, чтобы увидеть название текущей песни во всплывающем сообщении. Наконец, вы можете наслаждаться музыкой во время игры!
Межпроцессные взаимодействия
Каждое приложение Android работает в собственном процессе с уникальным идентификатором процесса. Когда вы запускаете приложение, система Android генерирует процесс и выполняет основное действие в основном потоке. Плюс этого в том, что приложение живет в изолированной среде, и другие приложения не могут его прервать.
Исходя из этого, Android позволяет запускать компоненты в другом процессе, который не используется для запуска приложения. Для этого вам нужно использовать тег процесса внутри AndroidManifest.xml. У процесса может быть случайное имя, например myNewProcess.
Многопроцессорность повышает безопасность вашего приложения и улучшает управление памятью. Однако, если вы его используете, вам нужно найти способ взаимодействия между различными процессами.
Вам нужно включить только один программный интерфейс — IBinder, но Android предоставляет три способа его определения:
Первый способ мы уже рассмотрели в этом туториале, но не стесняйтесь изучить и другие.
Что дальше?
Загрузите конечный проект, если что-то у вас не получилось.
Вы узнали много нового о сервисах Android и о том, как их по-разному использовать. Сервисы полезны для оптимизации приложений и улучшения взаимодействия с пользователем.
Android 12 внесет некоторые изменения в уведомления переднего плана. Ознакомиться с ними можно в официальной документации по Foreground Services.
Источник