A new way to publish apps using the Android App Bundle. Plugins Android studio adding a new module

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 Activityclick 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\u003e New\u003e 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

When we talk about plugins and modular applications, we primarily mean ordinary user software. However, modular design can be equally useful when developing rootkits and backdoors. By conventional means, updating such software is too pale, and it’s not always possible, but quietly loading a module with new functionality over the network is welcome. And if you take out the key functionality in the modules and delete them immediately after loading, then you can seriously ruin the life of the reverser.

Instead of introducing

In classic Java, there is a class called java.lang.ClassLoader. Its task is to load the bytecode of the specified class (file with the extension .class) into the virtual machine during application execution. Then you can create an object of this class and call its methods using reflection. This is a way to dynamically load code that can be used to write applications with extensible functionality, or, more simply, support for plugins.

In Android there is no Java virtual machine and there is no ClassLoader class, but there is its analogue DexClassLoader that performs exactly the same function, but with respect to Dalvik bytecode (and .dex files instead of .class, respectively). And, unlike desktop Java, where it is easier to put the desired jar file in CLASSPATH and not bother with dynamic loading, in Android this approach offers really many advantages, the main one of which is that the functionality of the application can be expanded and updated invisibly to the user and without asking him anything. At any time, your application can download the class file from the server, download, and then delete the file.

In addition, classes can be stored directly in the APK package and loaded at application startup. The profit here is that the code of the loaded classes will be separated from the code of the application itself and be in the APK "not at the address"; tools like apktool, which reversers love to use, simply won't be seen. On the other hand, it is more likely to be a defense against a fool, since a normal reverse will quickly see what's what.

Be that as it may, dynamic class loading is a very useful thing when writing off-white applications, so any security specialist should know how this mechanism works and how it is used in trojans.

Simplest example

   // The path to the jar archive with our class String modFile \u003d "/sdcard/myapp/module.jar"; // Path to the application private directory String appDir \u003d getApplicationInfo (). DataDir; // Load the file from the disk DexClassLoader classLoader \u003d new DexClassLoader (modFile, appDir, , getClass (). GetClassLoader ()); // Load the class, create an object and try to call the run () method using reflection try (Class c \u003d classLoader.loadClass ("com.example.modules.simple.Module"); Method m \u003d c.getMethod ("run", null); m.invoke (c.newInstance (), null);) catch (Exception e) (e.printStackTrace ();)

In general, everything is simple: the code loads the jar archive /sdcard/myapp/module.jar with our class, loads the com.example.modules.simple.Module class from it, creates an object and calls the run () method. Pay attention to three points:

  • DexClassLoader can load both “simple” .dex files and jar archives, the latter being preferable due to compression and the ability to use a digital signature;
  • the second argument to the DexClassLoader constructor is the directory that it uses to save the optimized bytecode (odex), for simplicity we specify the private directory of the application itself;
  • as an argument to the loadClass method, you must always specify the class address along with the package name.

To test this code for performance, create a simple module:

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

Take your time to create a new project in Android Studio, you can throw this code in notepad and assemble it in a jar archive directly from the command line:

Javac -classpath /path/do/SDK/platforms/android-23/android.jar Module.java /path/do/SDK/build-tools/23.0.3/dx --dex --output \u003d module.jar Module. class

Make sure that the platforms / android-23 and build-tools / 23.0.3 directories exist, in your case their names may differ.

If everything goes smoothly, you get the module.jar file at the output. All that remains is to add the bootloader code to the application, put module.jar on the memory card, build and run the application.

Down with reflection

Reflection is a good thing, but in this case it only interferes. It is not difficult to call one method without arguments with its help, however, if we want our application to have a developed API of modules with many methods that take several parameters, we need to come up with something more convenient. For example, use a predefined interface that each module will implement.

Applying this approach to the above example, we get the following three files:

  1. ModuleInterface.java file with API description: package com.example.modules; public interface ModuleInterface (public void run ();)
  2. Module.java file with the implementation of our module: 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. New module loader (put into your application): String modFile \u003d "/sdcard/myapp/module.jar"; String appDir \u003d getApplicationInfo (). DataDir; DexClassLoader classLoader \u003d new DexClassLoader (modFile, appDir, , getClass (). GetClassLoader ()); // Load the class and create an object with the interface ModuleInterface ModuleInterface module; try (Class   class \u003d classLoader.loadClass ("com.example.modules.simple.Module"); module \u003d (ModuleInterface) class.newInstance (); ) catch (Exception e) (e.printStackTrace ();) module.run ()

It's all. Now we can work with the module as an ordinary object. Moreover, the system itself will reject modules (classes) that are incompatible with the interface, even at the boot stage, so we won’t have to wonder if there is a method we need in the module.

When there are a lot of modules

We dealt with one module, but what if there are a lot of them? How to keep records of these modules and not get lost among them? In fact, everything is simple - you can use hashmap for this. Change the bootloader again:

Continuation is available only to participants

Option 1. Join the community "site" to read all the materials on the site

Membership in the community during the specified period will open you access to ALL Hacker materials, increase your personal cumulative discount and allow you to accumulate a professional Xakep Score!

To create a module in Android Studio   choose

File\u003e New\u003e New Module

Then there are 2 options. If you plan to create a “clean” java library, specify Java library , as a result, the code of such a library is compiled into Jar file. This is convenient, since you can use it not only in Android applications. If you are going to use android-specific things and you need classes from android. * Packages, then create Android library which at compilation is going to Aar   file. In this case, you will like the last option.

IMPORTANT:   In minSDKVersion (module build.gradle files), the application must match or be larger than that specified in the library module. The specified buildToolsVersion must be installed in the Android SDK. Each library module generates its own resource class (* .R.class). When Android libraries are added to the project and its assembly takes place, their resources merge, which can lead to conflicts. Therefore, the documentation defines the following conventions:

  • If the application resource ID matches the resource ID in the library, then the application resource is used
  • If the resource ID matches in different libraries, then the library resource is used, which is indicated first in the list of dependencies (located above in the dependecies block)
  • To avoid the conflicts described above, it is recommended to use a prefix or other sequential resource naming scheme that will be unique for each of the modules (or unique for the whole application)

Connect Android Library

Android libraries are connected as dependencies (if the library was created as a separate project in AndroidStudio). There are also 2 options:

1. Either add a compiled AAR (or JAR) file:

File\u003e New Module - Import .JAR / .AAR Package\u003e Next - enter the path to the ARR (or JAR) file\u003e Finish

2. Either import the library from source:

File\u003e New\u003e Import Module - enter the path to the directory where the library sources\u003e Finish are located

IMPORTANT:   make sure the Android library name has been added to settings.gradle

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

and appeared in the dependencies block of the file build.gradle   applications

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

Android libraries can contain resources, other JAR libraries, their own AndroidManifest.xml.

Compiled Android Library Structure

The compiled Android library is a regular zip archive with the extension .arr, which contains the following required files and directories:

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

and optional:

  • / assets /
  • / libs / name.jar
  • / jni / abi_name/name.so (where abi_name one of the supported Android ABIs)
  • /proguard.txt
  • /lint.jar


Android Studio: the module will not appear in the “Edit Configuration” (13)

Sometimes errors exist in the Android manifest due to the fact that there is a cross like image through the launch / debug configuration, so try to see if the Android manifest has any errors in one case.

I imported the project into Android Studio with several subprojects.

I want to run a subproject.

I have successfully done this build.gradle subprojects as a module.

To launch it, I went to Run\u003e Edit Configurations\u003e Android Application.

Problem. When I try to select a module, none of them appear in the drop-down list.

Why is this?

EDIT: It appears as a module under Groovy, but not in an Android application. How can I get it in an Android app?

goto Android \u003e\u003e Gradle Scripts \u003e\u003e Build Gradle (Module: app)

make sure the first line of this file looks like this.

Apply plugin: "com.android.library"

This was fixed for me by simply restarting Android Studio .. Like the good old days of Eclipse

For my case, a newbie, I roared my project, not sure how, but it would not work anymore and complained about the manifest, R, that's all. I realized that some, as in my settings. Gradle does not include ": app", only I added this, I was on the road again.

Finally, I found out why the module is not displayed when I add the configuration for AndroidTests for the com.android.library module.

If you build.gradle your library module in the build.gradle application as follows:

Compile project (": yourlibrary")

Since it is compiled with release mode for the library module by default, you cannot run Android Tests for it, so it will not appear in the list of modules. I fixed it with the following modification:

Add the following configuration to build.gradle of your library module:

PublishNonDefault true

build.gradle the following changes, you can debug compile your library by editing the build.gradle of your application module, for example:

Compile project (": yourlibrary") + debugCompile project (path: ": yourlibrary", configuration: "debug") + releaseCompile project (path: ": yourlibrary", configuration: "release")

Then sync it and you will find it in the list.

It seems that different solutions work for people with a difference, because I just close the project, and importing it solved the problem again.

I had a similar problem, when I selected the parent directory of my project, I resolved Close Project -\u003e Delete a project from Android Studio -\u003e Import Project   by selecting the right file build.gradle .

Make sure you select the correct build.gradle file during import.

Make sure your build.gradle

Apply plugin: "com.android.application"

After you have changed, repeat the synchronization.

This happens mainly when copying a library project and creating it. The solution would be to add

Apply plugin: "com.android.application"

in the build.gradle file, instead

Apply plugin: "com.android.library"

Then do gradient synchronization

orderEntry type \u003d "library" exported \u003d "" name \u003d "appcompat-v7-19.1.0" level \u003d "project" /\u003e

I fixed this by adding edges to module settings   . They are missing. \u003e open module settings > Borders > Add faces   (“+” sign at the top)\u003e Android   . After adding faces you will have modules.

UPDATE:

For the latest version of the gradient Facets have been removed   , now you can directly add modules. right click on the project > open module settings > Add module   (at the top of the “+” sign)\u003e Phone and tablet app   (now you can create a new module and configure it).

add your moudle to your apps. iml file like: orderEntry type \u003d "module" module-name \u003d "yourmoudlename" exported \u003d ""

At the recent Google I / O 2018Among the many innovations, they also announced the addition of a new application format.

This format is called Android App Bundle   and is an improved way to build your application. Using it, you can easily optimize the size of the application, without having to make any changes to the code. The Android App Bundle includes all the compiled code and resources, then filtering out what is not needed by a specific device.

Important!   Currently, the Android App Bundle only works in the preview version of Android Studio. Latest version Android Studio 3.2 Canary   available.

Android App Bundle Format

Android App Bundle is a file (with extension .aab), which is uploaded to Google. Each bundle includes compiled code and resources for all application modules and supported device configurations.

Simply put, bundles are signed ZIP files that organize application code and resources into modules.

From these modules, Google Play generates various APKs that are provided to users, such as: basic APKs, dynamic feature APKs, configuration APKs and (for devices that do not support shared APKs) multi-APKs. The blue directories represent the code and resources that Google Play uses to create a configuration APK for each module.

Note:   a bundle must be created for each unique application or applicationID. That is, if you use several product flavor in your application to create different APKs, and each of these branches uses a unique applicationID, then you will need to create a separate bundle for each branch.

The code and resources for each module are organized similarly to the standard APK, and this is logical, since each of these modules can be generated as a separate APK. Below you can see a more detailed description of some files and directories of the Android App Bundle:

  • base /, feature1 /, feature2 /. Each of these directories is an application module. The application base module is always contained in the bundle base directory. Directories with additional features, each of which is assigned a special name, are located separately.
  • files Protocol Buffer (.pb). These files contain metadata that helps describe the contents of the bundle in application stores. For instance, Bundleconfig.pblocated in the root directory of the bundle provides information about the bundle itself, for example, which version build tools   used for assembly. Other files, such as recourse.pb   and native.pb, describe how specific code and resources should be used for various device configurations. Google Play uses this information to generate an APK optimized for the user's device.
  • manifest /. Unlike APKs, bundles store the AndroidManifest.xml file of each module in a separate directory.
  • dex /. Unlike APKs, bundles store the DEX files of each module in a separate directory.
  • root /. This directory stores files that are later moved to a directory root   any APK that includes the module in which this directory is located. For example, a directory base / root /   a bundle may include Java resources that are loaded by the application using Class.getResources (). These files are later moved to the root directory of the application’s APK and each multi-APK that Google Play generates. Paths in this directory are also saved, that is, subdirectories also move along with root.
    Note:if the contents of this directory conflict with other files and directories in the root of the APK, the Play Console will reject the download of the bundle. For example, you cannot include the root / lib / directory, as it will conflict with the lib directory already in the APK.
  • res /, lib /, assets /.   These directories are identical to those used in the standard APK. When downloading the application, Google Play checks in these directories and packages only those files that match the configuration of the target device.

Build App Bundle with Android Studio

Creating a bundle using Android Studio is very similar to creating an APK. For assembly, just select the menu Build - Build Bundle (s) / APK (s)\u003e Build Bundle (s)   and the IDE will create a bundle for the selected build option and place it in the directory // build / outputs / bundle /.

If you create a bundle for the debug version of the application, Android Studio will automatically sign the bundle using the debug key of the signature. To download a bundle on Google Play, it must be signed.

After Android Studio completes the creation of a signed bundle, it can be opened and analyzed. Bundle analysis allows you to check the contents and works similarly APK Analyzer.

To create the App Bundle, the IDE uses the same open source tool called bundletool, which Google Play uses for subsequent conversion of the bundle into signed APKs.

Before you can upload a bundle to the Google Play console, you must sign it. To create a signed App Bundle, do the following:


After Android Studio completes the creation of a signed bundle, it can be found and analyzed by selecting the appropriate option in the pop-up notification. If you chose to export the signature key, you can quickly access it by clicking on the down arrow in the lower right corner of the pop-up notification to expand it, and then selecting Show Exported Key File.

Download the App Bundle to the Google Play Console

After the bundle is created, it can be downloaded to Google Play to verify, test or publish the application. Before starting work, the following conditions must be met:

  1. Register in the program   Google Play App Signing.
  2. If the application includes dynamic feature modules, then it can be downloaded and tested through the internal test track of the Google Play console. However, in order to publish the application, you need to accept the Dynamic Feature program, which is currently in beta.
  3. Google Play supports downloading apps no larger than 100 MB.

Explorer analysis using explorer

When the bundle is uploaded, Google Play automatically generates split APKs and multi-APKs for all device configurations supported by the application. In the Play Console, you can use the App Bundle Explorer to view all of the APK options generated by Google Play; data analysis such as supported devices and APK size savings; Download created APKs for testing.

Application update

After downloading the application to the Play Console, to update the application, it is enough to raise the version code, as well as create and download a new bundle. Then Google Play will generate updated APKs with the new version code and will provide them as needed.

Conclusion

Using the Android App Bundle offers great benefits for optimizing your APK apps. Using this method, we updated one of our applications, “Password Manager for Wi-Fi Networks,” replacing the standard APK with the App Bundle in it. Thus, the size of the APK files decreased by a whole megabyte, which is a very good result.

In addition, Google is currently testing an addition to the App Bundle, Dynamic feature modules, with which you can break the basic APK into parts that will be downloaded if necessary, while this technology is in beta.

Perhaps the only drawback of the bands at the moment is the need to use the preview version of Android Studio, but this problem is temporary.

Technology Overview