Новый способ публикации приложений с помощью Android App Bundle. Java - редактирование - manifest android structure Андроид студио добавление нового модуля

Установленные плагины находятся в меню File | Settings... | Plugins . Кнопка Browse repositories... позволяет найти плагин в репозитории. Кнопка Install plugin from disk... позволяет установить плагин с диска, если вы его скачали самостоятельно.

Rainbow Brackets

"Радужные скобки" позволяют пометить каждую пару скобок своим индивидуальным цветом. Это помогает визуально видеть, где находится область кода.

Заменяет все индикаторы прогресса в студии на няшного котика. Если вы серьёзный программист, то просто обязаны установить плагин . Совместимо с другими средами разработки на основе IntelliJ IDEA: PhpStorm, WebStorm, PyCharm, RubyMine, AppCode, CLion, Gogland, DataGrip, Rider, MPS.

Появляется везде. Например, при загрузке проекта.

Во время работы при синхронизации чего-либо.

RoboPOJOGenerator

Удобный генератор готовых Java и Kotlin POJO классов из JSON: GSON, FastJSON, AutoValue (GSON), Logan Square, Jackson.

ADB Idea

Плагин для Android Studio/Intellij IDEA для быстрых операций над приложением:

  • Uninstall App - удалить приложение из устройства
  • Kill App - убить приложение (удалить из памяти)
  • Start App - запустить приложение
  • Restart App - перезапустить приложение
  • Clear App Data - очистить данные
  • Clear App Data and Restart - очистить данные и перезапустить

После установки эти команды можно найти через Tools | Android | ADB IDEA .

Также можно вызвать окно поиска действий через комбинацию клавиш Ctrl+Shift+A и с помощью символов ADB быстро найти конкретную команду.

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

Для создания модуля в Android Studio выбираете

File > New > New Module

Далее есть 2 варианта. Если вы планируете создать «чистую» java-библиотеку, в качестве типа указывайте Java Library , в итоге код такой библиотеки скомпилируется в JAR файл. Это удобно, так как вы сможете использовать ее не только в Android приложениях. Если же вы собираетесь использовать android-специфичные вещи и вам понадобятся классы из пакетов android.* , то создавайте Android Library , которая при компиляции собирается в AAR файл. В данном случае вам понядобится последний вариант.

ВАЖНО: В minSDKVersion (файлы build.gradle модулей) приложения должен совпадать или быть больше, чем указанный в модуле библиотеки.Указанные buildToolsVersion должны быть установлены в Android-SDK. Каждый модуль библиотеки генерирует свой класс ресурсов (*.R.class). Когда Android библиотеки добавляются в проект и происходит его сборка, то их ресурсы сливаются, что может привести к конфликтам. Поэтому в документации определены следующие соглашения:

  • Если ID ресурса приложения совпадает с ID ресурса в библиотеке, то используется ресурс приложения
  • Если ID ресурса совпадает в разных библиотеках, то используется ресурс библиотеки, которая указана первой в списке зависимостей (находится выше в блоке dependecies)
  • Для избежания описанных выше конфликтов рекомендуется использовать префикс или другую последовательную схему именования ресурсов, которая будет уникальна для каждого из модулей (или уникальна для всего приложения вцелом)

Подключение Android библиотеки

Подключаются Android библиотеки как зависимости (если библиотека была создана как отдельный проект в AndroidStudio). Тут есть так же 2 варианта:

1.Либо добавить скомпилированный AAR (или JAR) файл:

File > New Module - Import .JAR/.AAR Package > Next - вводите путь до ARR (или JAR) файла > Finish

2.Либо импортировать библиотеку из исходников:

File > New > Import Module - вводите путь до директории, в которой находятся исходники библиотеки > Finish

ВАЖНО: убедиться, что имя Android библиотеки было добавлено в settings.gradle

Include ":app", ":core", ":personal", ":client"

и появилась в блоке dependencies файла build.gradle приложения

Dependencies { compile project(":core") compile project(":personal") compile project(":client") }

Android библиотеки могут содержать в себе ресурсы, другие JAR библиотеки, собственный AndroidManifest.xml .

Структура скомпилированной Android библиотеки

Скомпилированная Android библиотека представляет собой обычный zip архив с расширением.arr , который содержит следующие обязательные файлы и директории:

  • /AndroidManifest.xml
  • /classes.jar
  • /res/
  • /R.txt

и необязательные:

  • /assets/
  • /libs/name .jar
  • /jni/abi_name /name .so (где abi_name один из поддерживаемых Android ABIs)
  • /proguard.txt
  • /lint.jar

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

Вместо введения

В классической Java есть класс под названием java.lang.ClassLoader . Его задача - загружать байт-код указанного класса (файл с расширением.class) в виртуальную машину во время исполнения приложения. Затем можно создать объект этого класса и вызывать его методы с помощью рефлексии. Такой вот способ динамической загрузки кода, который можно использовать для написания приложений с расширяемой функциональностью, или, попросту говоря, поддержкой плагинов.

В Android нет виртуальной машины Java и нет класса ClassLoader, но есть его аналог DexClassLoader, выполняющий ровно ту же функцию, но в отношении байт-кода Dalvik (и файлов.dex вместо.class соответственно). И, в отличие от настольной Java, где проще положить нужный jar-файл в CLASSPATH и не возиться с динамической загрузкой, в Android такой подход дает действительно много преимуществ, главное из которых в том, что функциональность приложения можно расширять и обновлять незаметно для пользователя и ни о чем его не спрашивая. В любой момент твое приложение может скачать файл с классом с сервера, загрузить, а затем удалить файл.

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

Как бы там ни было, динамическая загрузка классов - очень полезная штука при написании не совсем «белых» приложений, поэтому любой security-специалист должен знать, как этот механизм работает и как он используется в троянах.

Простейший пример

// Путь до jar-архива с нашим классом String modFile = "/sdcard/myapp/module.jar"; // Путь до приватного каталога приложения String appDir = getApplicationInfo().dataDir; // Подгружаем файл с диска DexClassLoader classLoader = new DexClassLoader(modFile, appDir, null, getClass().getClassLoader()); // Загружаем класс, создаем объект и пробуем вызвать метод run() с помощью рефлексии try { Class c = classLoader.loadClass("com.example.modules.simple.Module"); Method m = c.getMethod("run", null); m.invoke(c.newInstance(), null); } catch (Exception e) { e.printStackTrace(); }

В целом здесь все просто: код загружает jar-архив /sdcard/myapp/module.jar с нашим классом, загружает из него класс com.example.modules.simple.Module , создает объект и вызывает метод run() . Обрати внимание на три момента:

  • DexClassLoader умеет загружать как «просто» файлы.dex , так и jar-архивы, последние предпочтительнее из-за сжатия и возможности использовать цифровую подпись;
  • второй аргумент конструктора DexClassLoader - это каталог, который он использует для сохранения оптимизированного байт-кода (odex), для простоты мы указываем приватный каталог самого приложения;
  • в качестве аргумента метода loadClass всегда необходимо указывать адрес класса вместе с именем пакета.

Чтобы проверить данный код на работоспособность, создадим простейший модуль:

Package com.example.modules.simple.Module; import android.util.Log; public class Module { public void run() { Log.d("Module", "I am alive!!!"); } }

Не торопись создавать новый проект в Android Studio, можешь накидать этот код в блокноте и собрать его в jar-архив прямо из командной строки:

Javac -classpath /путь/до/SDK/platforms/android-23/android.jar Module.java /путь/до/SDK/build-tools/23.0.3/dx --dex --output=module.jar Module.class

Удостоверься, что каталоги platforms/android-23 и build-tools/23.0.3 существуют, в твоем случае их имена могут отличаться.

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

Долой рефлексию

Рефлексия - хорошая штука, но в данном случае она только мешает. Один метод без аргументов с ее помощью вызвать нетрудно, однако, если мы хотим, чтобы наше приложение имело развитый API модулей с множеством методов, принимающих несколько параметров, нужно придумать что-то более удобное. Например, использовать заранее определенный интерфейс, который будет реализовывать каждый модуль.

Применив такой подход к приведенному выше примеру, мы получим следующие три файла:

  1. Файл ModuleInterface.java с описанием API: package com.example.modules; public interface ModuleInterface { public void run(); }
  2. Файл Module.java с реализацией нашего модуля: package com.example.modules.simple.Module; import android.util.Log; public class Module implements ModuleInterface { public void run() { Log.d("Module", "I am alive!!!"); } }
  3. Новый загрузчик модуля (помести в свое приложение): String modFile = "/sdcard/myapp/module.jar"; String appDir = getApplicationInfo().dataDir; DexClassLoader classLoader = new DexClassLoader(modFile, appDir, null, getClass().getClassLoader()); // Загружаем класс и создаем объект с интерфейсом ModuleInterface ModuleInterface module; try { Class class = classLoader.loadClass("com.example.modules.simple.Module"); module = (ModuleInterface) class.newInstance(); } catch (Exception e) { e.printStackTrace(); } module.run()

Это все. Теперь мы можем работать с модулем, как с обычным объектом. Более того, система сама отбракует модули (классы), несовместимые с интерфейсом, еще на этапе загрузки, поэтому нам не придется задаваться вопросами, а есть ли в модуле нужный нам метод.

Когда модулей много

С одним модулем разобрались, но что, если их будет много? Как вести учет этих модулей и не потеряться среди них? На самом деле все просто - для этого можно использовать hashmap. Еще раз изменим загрузчик:

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

Вариант 1. Присоединись к сообществу «сайт», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score!

Введение

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

В этом смысле в царстве Android нет достаточно комфортных сред разработки, как это, впрочем, и полагается программам в мире бесплатных операционных систем. Ещё до недавнего времени центральным средством разработки считался Eclipse со специализированными плагинами. Однако летом 2013 года Google представил на суд общественности новую IDE — Android Studio , основанную на давнишнем конкуренте Eclipse — системе IntelliJ IDEA . Надо сказать, что несмотря на раннюю версию системы, не вошедшую ещё даже в стадию Beta, она уже превосходит удобством Eclipse.

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

После такого большого вступления, я всего лишь расскажу, как в Android Studio можно генерировать конечные apk-файлы, готовые к распространению, ибо есть нюансы. Надеюсь, моя статья хоть как-то облегчит жизнь начинающим пользователям этой, пожалуй, лучшей на сегодняшний день IDE для программирования под Android.

Ручной способ

  1. В левом нижнем углу Android Studio есть маленькая кнопочка, управляющая отображением специальных ярлыков у краёв экрана. Ярлыки открывают различные вспомогательные окна. Кроме того, при простом наведении на эту кнопочку указателя мыши, появляется список всех этих окон для быстрого открытия нужного. Откроем окно Build Variants и напротив нашего модуля в поле Build Variant переключим режим сборки с debug на release.
  2. В основном меню открываем Build → Generate Signed APK. Возникает сообщение, которое, немного перефразируя, можно перевести примерно так: «Для проектов, собирающихся утилитой Gradle, информация о подписи и порядок подписывания apk-файлов должны быть прописаны в специальном сценарии. Настройте сценарий, как это описано в руководстве пользователя: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Signing-Configurations . Затем запустите "Gradle assembleRelease", и получите сгенерированный apk-файл в папке build/apk/ » Это сообщение как раз настоятельно рекомендует нам использовать второй способ создания apk-файла. Принимаем информацию к сведению, но продолжаем ручной способ, нажав OK.
  3. Открывается окно помощника генерации подписи для apk-файла. Мы уже знаем, что все распространяемые приложения для Android должны иметь цифровую подпись автора, иначе приложение не установится на устройства пользователей. Сгенерированная подпись должна храниться в специальном файле-хранилище, расположенном на вашем компьютере, откуда потом она будет извлекаться для подписания apk-файлов. При этом одно хранилище может хранить несколько подписей для разных apk-файлов. Кроме того, одна и та же подпись может использоваться для подписания разных apk-файлов. Итак, для создания хранилища нажимаем кнопку Create New… и заполняем открывшиеся в окне поля:
    1. Путь для размещения файла хранилища
    2. Пароль и подтверждение для доступа к хранилищу
    3. Имя подписи, по которому она будет вызываться
    4. Пароль и подтверждение для доступа к подписи
    5. Срок действия подписи (по умолчанию 25 лет, оставляем без изменений)
    6. Хотя бы одно из полей сертификата. Обычно заполняют имя и фамилию, город и страну (RU).
  4. Нажимаем OK. Окно закрывается, и мы видим, что все поля в предыдущем окне автоматически заполнились введёнными нами данными. Ставим галочку в поле Remember Password, чтобы каждый раз не набирать пароль, и нажимаем OK.
  5. В следующем окне контролируем путь и имя apk-файла. По умолчанию оно равно имени модуля. Включаем галочку Run ProGuard, чтобы наш файл был оптимизирован, и можем даже поменять файл конфигурации proguard-android.txt на proguard-android-optimize.txt для более жёсткой оптимизации (хотя это может быть чревато для некоторых экзотичных смартфонов). Нажимаем Finish и ждём, посматривая в строку состояния.
  6. Когда сборка проекта закончится, отобразится окошко с предложением открыть папку с полученным apk-файлом. Открываем её и видим наш файл.

Скажу сразу, что несмотря на то, что я ставлю галочку в поле Run ProGuard, он у меня почему-то не отрабатывает, и apk-файл остаётся неоптимизированным. Возможно, это пережитки ранней версии Android Studio (у меня версия 0.5.4 ). Но выйти из положения достаточно просто, включив эту галочку непосредственно в файле сценария утилиты ProGuard. Найдите в окне проекта внутри нашего модуля файл build.gradle. В секции android → buildTypes → release, отвечающей за генерацию релиза, поменяйте параметр runProguard с false на true.

Не забудьте после редактирования файла сценария синхронизировать с ним ваш проект. Для этого в панели инструментов нажмите кнопку Sync Project with Gradle Files (стрелочка вниз из зелёного кружка) или ссылку Sync Now во всплывшей в верхней части исходника жёлтой полосе сообщения. После синхронизации можно снова попробовать собрать apk-файл, начиная со второго пункта нашей инструкции. Только в этот раз вместо генерации нового хранилища используем уже созданное. Все наши пароли и настройки сохранились, поэтому нам только остаётся нажимать во всплывающих окнах OK-Next-Finish. Обратите внимание, что вновь сгенерированный apk-файл стал немного меньше, чем в прошлый раз.

Автоматический способ

Автоматический способ позволяет генерировать apk-файл без ввода паролей при каждом запуске приложения на выполнение, а также командой assembleRelease, добавленной в список конфигураций и выполняющейся той же кнопкой Run.

Для включения автоматического режима надо внести в уже знакомый нам файл сценария build.gradle новую секцию, содержащую в том числе информацию о подписи:


signingConfigs { release { storeFile file("C:\\Users\\ИмяПользователя\\KEYSTORE.jks") storePassword "ПарольХранилища" keyAlias "ИмяПодписи" keyPassword "ПарольПодписи" } buildTypes { release { minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } }

Вместо файла настроек "proguard-android.txt" можно вписать файл ещё более оптимизированных настроек "proguard-android-optimize.txt". Это позволит ещё немного сократить объём apk-файла.

Для внесения этой секции в настройки откроем файл build.gradle, расположенный внутри нашего модуля и закомментируем секцию buildTypes. Вместо неё вставим вышеприведённую секцию. Не забудьте поменять путь к вашему файлу ключей, который вы создали в первой части статьи при ручном создании apk-файла, а также вписать правильное имя подписи и оба пароля.

После внесения изменений в файл нажимаем в панели инструментов кнопку Sync Project with Gradle Files (стрелочка вниз из зелёного кружка) или ссылку Sync Now во всплывшей вверху жёлтой информационной полосе, чтобы синхронизировать изменённые настройки с проектом. Всё, автоматический режим настроен!

Теперь, чтобы иметь возможность генерировать apk-файл без запуска приложения, добавим отдельную команду запуска генерации apk-файла в список конфигураций (комбо-бокс в панели инструментов). Откроем окошко Gradle Tasks, нажав на ярлык Gradle у правого края экрана, или выбрав его во всплывающем списке кнопки, расположенной в левом нижнем углу Android Studio. В секции All tasks раскрываем список задач для нашего модуля и правой кнопкой щёлкаем по задаче assembleRelease. В появившемся контекстном меню выбираем пункт Create… и выбранная задача добавится в список конфигураций.

Теперь мы можем генерировать релиз и без запуска программы на выполнение, просто выбрав в списке конфигураций команду assembleRelease и нажав кнопку Run. Результат автоматического создания apk-файла будет находится в папке build/apk/. Там будут два файла: ИмяМодуля-release-unaligned.apk и ИмяМодуля-release.apk. Первый файл — это полуфабрикат. Он уже подписан но ещё не выровнен. Второй файл — уже выровненный. Это и есть наш конечный apk-файл, который мы уже можем переименовать и свободно распространять.

Замечу, что выравнивание файла гарантирует, что все несжатые данные будут начинаться с позиции, кратной 4 байтам по отношению к началу файла. Это обеспечит оптимизацию производительности программы на устройстве. Когда файл выровнен, Android способен читать информацию из файла по мере необходимости, а не загружать в память весь пакет целиком. В итоге уменьшается объем оперативной памяти, потребляемой запущенным приложением.

Modules provide a container for your app"s source code, resource files, and app level settings, such as the module-level build file and Android manifest file. Each module can be independently built, tested, and debugged.

Android Studio uses modules to make it easy to add new devices to your project. By following a few simple steps in Android Studio, you can create a module to contain code that"s specific to a device type, such as Wear OS or Android TV. Android Studio automatically creates module directories, such as source and resource directories, and a default build.gradle file appropriate for the device type. Also, Android Studio creates device modules with recommended build configurations, such as using the Leanback library for Android TV modules.

This page describes how to add a new module for a specific device.

Android Studio also makes it easy to add a library or Google Cloud module to your project. For details on creating a library module, see Create a Library Module .

Create a new module

To add a new module to your project for a new device, proceed as follows:

  1. Click File > New > New Module .
  2. In the Create New Module window that appears, Android Studio offers the following device modules:
    • Phone & Tablet Module
    • Wear OS Module
    • Android TV Module
    • Glass Module
    Select the module for the device you want, and then click Next .
  3. In the Configure your new module form, enter the following details:
    • Application Name : This name is used as the title of your app launcher icon for the new module.
    • Module Name : This text is used as the name of the folder where your source code and resources files are visible.
    • Package Name : This is the Java namespace for the code in your module. It is added as the package attribute in the module"s Android manifest file .
    • Minimum SDK : This setting indicates the lowest version of the Android platform that the app module supports. This value sets the minSdkVersion attribute in the build.gradle file, which you can edit later.

    Then click Next .

  4. Depending on which device module you selected, the following page displays a selection of appropriate code templates you can select to use as your main activity. Click an activity template with which you want to start, and then click Next . If you don"t need an activity, click Add No Activity , click Finish , and then you"re done.
  5. If you chose an activity template, enter the settings for your activity on the Customize the Activity page. Most templates ask for an Activity Name , Layout Name , Title , and Source Language , but each template has activity-specific settings. Click Finish . When you create an app module with an activity template, you can immediately run and test the module on your device.

Android Studio creates all the necessary files for the new module and syncs the project with the new module gradle files. Adding a module for a new device also adds any required dependencies for the target device to the module"s build file.

Once the Gradle project sync completes, the new module appears in the Project window on the left. If you don"t see the new module folder, make sure the window is displaying the Android view .

Import a module

To import an existing module into your project, proceed as follows:

  1. Click File > New > Import Module .
  2. In the Source directory box, type or select the directory of the module(s) that you want to import:
    • If you are importing one module, indicate its root directory.
    • If you are importing multiple modules from a project, indicate the project folder. For each module inside the folder, a box appears and indicates the Source location and Module name . Make sure the Import box is checked for each module that you want to import.
    If your module(s) have other dependencies, they will be listed to import under Additional required modules .
  3. Type your desired module name(s) in the Module name field(s).
  4. Click Finish.

Next steps

Once you"ve added a new module, you can modify the module code and resources, configure module build settings, and build the module. You can also run and debug the module like any other app.

  • To learn about build settings for a module, see The Module-level Build File .
  • To build and run a specific module, see Select and build a different module .

You"ll also want to add code and resources to properly support the new device. For more information about how to develop app modules for different device types, see the corresponding documentation:

  • For Wear OS modules:
  • For Android TV modules:
  • For Glass modules: GDK Quick Start

As you develop your new module, you might create device independent code that is already duplicated in a different app module. Instead of maintaining duplicate code, consider moving the shared code to a library module and adding the library as a dependency to your app modules. For more information on creating a library module and adding it as a dependency, see

Понравилось? Лайкни нас на Facebook