Создание нескольких APK для разных текстур GL

Если вы публикуете свое приложение в Google Play, вам необходимо создать и загрузить пакет Android App Bundle . Когда вы это сделаете, Google Play автоматически создаст и предоставит оптимизированные APK-файлы для конфигурации устройства каждого пользователя, поэтому они загружают только тот код и ресурсы, которые им необходимы для запуска вашего приложения. Публикация нескольких APK-файлов полезна, если вы не публикуете их в Google Play, но вам необходимо самостоятельно создавать, подписывать и управлять каждым APK-файлом.

При разработке приложения Android для использования нескольких APK-файлов в Google Play важно с самого начала принять некоторые передовые методы и избежать ненужных головных болей в дальнейшем процессе разработки. В этом уроке показано, как создать несколько APK-файлов вашего приложения, каждый из которых поддерживает свое подмножество форматов текстур OpenGL. Вы также получите некоторые инструменты, необходимые для того, чтобы максимально упростить поддержку нескольких кодовых баз APK.

Подтвердите, что вам нужно несколько APK

Пытаясь создать приложение, которое работает на всех доступных устройствах под управлением Android, естественно, вы хотите, чтобы ваше приложение выглядело наилучшим образом на каждом отдельном устройстве, несмотря на то, что не все они поддерживают один и тот же набор текстур GL. Поначалу может показаться, что поддержка нескольких APK — лучшее решение, но зачастую это не так. Раздел «Использование одного APK вместо» руководства для разработчиков нескольких APK содержит некоторую полезную информацию о том, как сделать это с помощью одного APK, в том числе о том, как определить поддерживаемые форматы текстур во время выполнения . В зависимости от вашей ситуации может быть проще объединить все форматы с вашим приложением и просто выбрать, какой из них использовать во время выполнения.

Если вы можете справиться с этим, ограничение вашего приложения одним APK-файлом имеет ряд преимуществ, в том числе:

  • Публикация и тестирование стали проще
  • Необходимо поддерживать только одну кодовую базу
  • Ваше приложение может адаптироваться к изменениям конфигурации устройства.
  • Восстановление приложений на разных устройствах просто работает
  • Вам не нужно беспокоиться о рыночных предпочтениях, поведении при «обновлениях» с одного APK на другой или о том, какой APK подходит к какому классу устройств.

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

Напишите свои требования

Руководство разработчика Android содержит удобную ссылку на некоторые из распространенных поддерживаемых текстур на странице support-gl-texture . На этой странице также содержатся некоторые подсказки относительно того, какие телефоны (или семейства телефонов) поддерживают определенные форматы текстур. Обратите внимание: обычно рекомендуется, чтобы один из ваших APK-файлов поддерживал ETC1, поскольку этот формат текстур поддерживается всеми устройствами на базе Android, поддерживающими спецификацию OpenGL ES 2.0.

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

ETC1 АТИ PowerVR

Раскрашивание диаграммы не только делает это руководство менее монохромным. Оно также позволяет упростить общение внутри команды. Теперь вы можете просто называть каждый APK «синим», «зеленым» или «красным». «Тот, который поддерживает форматы текстур ETC1» и т. д.

Поместите весь общий код и ресурсы в проект библиотеки.

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

Примечание. Подробности реализации создания и включения проектов библиотек выходят за рамки этого урока, но вы можете быстро освоиться, прочитав «Создание библиотеки Android» .

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

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

Создание новых проектов APK

Для каждого APK, который вы собираетесь выпустить, должен быть отдельный проект Android. Для упрощения организации поместите проект библиотеки и все связанные проекты APK в одну родительскую папку. Также помните, что каждый APK должен иметь одно и то же имя пакета, хотя оно не обязательно должно использоваться совместно с библиотекой. Если бы у вас было 3 APK-файла по схеме, описанной ранее, ваш корневой каталог мог бы выглядеть следующим образом:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

После создания проектов добавьте проект библиотеки в качестве ссылки на каждый проект APK. Если возможно, определите начальное действие в проекте библиотеки и расширьте это действие в проекте APK. Наличие стартового действия, определенного в проекте библиотеки, дает вам возможность разместить всю инициализацию вашего приложения в одном месте, так что каждому отдельному APK не придется повторно реализовывать «универсальные» задачи, такие как инициализация Analytics, запуск проверок лицензии и любые другие. другие процедуры инициализации, которые не сильно меняются от APK к APK.

Настройте манифесты

Когда пользователь загружает приложение, которое использует несколько APK-файлов, через Google Play, правильный APK-файл выбирается с использованием нескольких простых правил:

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

Что касается GL-текстур, последнее правило важно. Это означает, например, что вам следует быть очень осторожными при использовании разных форматов GL в одном приложении. Если бы вы использовали PowerVR в 99% случаев, но использовали бы ETC1, скажем, для заставки… Тогда в вашем манифесте обязательно была бы указана поддержка обоих форматов. Устройство, поддерживающее только ETC1, будет считаться совместимым, ваше приложение будет загружено, и пользователь увидит несколько интересных сообщений о сбоях. Общим случаем будет то, что если вы используете несколько APK специально для разных устройств на основе поддержки текстур GL, для каждого APK будет один формат текстур.

На самом деле это немного отличает поддержку текстур от двух других размеров APK, уровня API и размера экрана. Любое устройство имеет только один уровень API и один размер экрана, и APK должен поддерживать ряд из них. Что касается текстур, APK обычно поддерживает одну текстуру, а устройство поддерживает множество. Часто бывает совпадение, когда одно устройство поддерживает множество APK, но решение одно и то же: коды версий.

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

Фуфон Нексус С Эво
ETC1 ETC1 ETC1
PowerVR АТИ ТЦ

Предполагая, что форматы PowerVR и ATI предпочтительнее ETC1, когда они доступны, чем в соответствии с правилом «выигрывает наибольший номер версии», если мы установим атрибут versionCode в каждом APK так, чтобы красный ≥ зеленый ≥ синий, тогда и красный, и зеленый всегда будут быть выбран вместо синего на устройствах, которые его поддерживают, и если когда-нибудь появится устройство, поддерживающее как красный, так и зеленый, будет выбран красный.

Чтобы все ваши APK-файлы находились на отдельных «дорожках», важно иметь хорошую схему кода версии. Рекомендуемый вариант можно найти в разделе «Коды версий» нашего руководства для разработчиков. Поскольку примерный набор APK имеет дело только с одним из трех возможных измерений, было бы достаточно разделить каждый APK на 1000 и увеличить его. Это может выглядеть так:

Синий: 1001, 1002, 1003, 1004...
Зелёный: 2001, 2002, 2003, 2004...
Красный: 3001, 3002, 3003, 3004...

Если сложить все это вместе, ваши манифесты Android, скорее всего, будут выглядеть примерно так:

Синий:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

Зеленый:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

Красный:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

Просмотрите контрольный список перед запуском

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

  • Все APK-файлы должны иметь одинаковое имя пакета.
  • Все APK должны быть подписаны одним и тем же сертификатом.
  • Дважды проверьте фильтры манифеста на предмет противоречивой информации (APK, который поддерживает только кексы на экранах XLARGE, никто не увидит).
  • Манифест каждого APK должен быть уникальным хотя бы для одного поддерживаемого экрана, текстуры OpenGL или версии платформы.
  • Попробуйте протестировать каждый APK хотя бы на одном устройстве. За исключением этого, на вашей машине разработки находится один из самых настраиваемых эмуляторов устройств в отрасли. С ума сойти!

Также стоит проверить скомпилированный APK перед выпуском на рынок, чтобы убедиться в отсутствии каких-либо сюрпризов, которые могут скрыть ваше приложение в Google Play. На самом деле это довольно просто с помощью инструмента «aapt». Aapt (инструмент упаковки ресурсов Android) — это часть процесса сборки для создания и упаковки ваших приложений Android, а также очень удобный инструмент для их проверки.

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Когда вы проверяете выходные данные aapt, обязательно убедитесь, что у вас нет конфликтующих значений для support-screens и совместимых-screens, а также что у вас нет непреднамеренных значений «uses-feature», которые были добавлены в результате разрешений, которые вы установлен в манифесте. В приведенном выше примере APK будет невидим для большинства, если не для всех, устройств.

Почему? Добавление необходимого разрешения SEND_SMS неявно добавило требование к функции android.hardware.telephony. Поскольку большинство (если не все) устройств xlarge представляют собой планшеты без телефонного оборудования, Google Play в этих случаях будет отфильтровывать этот APK до тех пор, пока не появятся будущие устройства, которые будут достаточно большими, чтобы сообщать о размере экрана xlarge, и будут обладать телефонным оборудованием.

К счастью, это легко исправить, добавив в манифест следующее:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

Требование android.hardware.touchscreen также добавляется неявно. Если вы хотите, чтобы ваш APK был виден на телевизорах без сенсорного экрана, вам следует добавить в свой манифест следующее:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

Заполнив контрольный список перед запуском, загрузите APK-файлы в Google Play. Приложению может потребоваться некоторое время, чтобы оно появилось при просмотре Google Play, но когда это произойдет, выполните последнюю проверку. Загрузите приложение на любые тестовые устройства, которые вам могут понадобиться, чтобы убедиться, что APK-файлы предназначены для нужных устройств. Поздравляем, все готово!