share

ENGINEERING

6min read

Android New Build System - real-world example

One of the tool every Android developer gets familiar with at the beginning of his journey is a build system. Originally built on top of Ant, unofficially substituted by Android Maven Plugin has had been recently completely rethought and renamed to New Build System.

New Build System

As of April 3rd, NBS is released in v0.3 which means it’s still under heavy development. One of the biggest changes is the removal of Ant and the switch to the so called Maven successor - Gradle. This echos the same path we’ve taken in Ameba.

Based on the release notes, NBS is currently ready to use with some limitations:

  • No IDE integration
  • No support of NDK
  • No support for Proguard
  • No Lint integration
  • No emma support
  • Binary packaging of library is still going through changes. Do not upload libraries to maven central (or other similar repos) just yet.

NBS provides some very useful samples. You can find and play with them here. If it’s not enough, another great example of a multi-module project build by Gradle is Spring Framework or its Android sibling - Spring for Android.

NBS and RoboSpock real-world example

A few days ago we decided to revitalize one of our open-source libraries - AndroidImageCache. We mainly worked on some improvements in downloading tasks queue and migrating all tests to Robolectric and Spock glued by our library - RoboSpock. One of the decisions we have also made was to make AndroidImageCache a real-world example of a multi-module Android project build by NBS and tested by RoboSpock

Modules

We started by reorganizing the project layout, and eventually finished with the following:

├── gradle          <--- gradle-related stuff, currently
|                        scripts to automatic upload archives to Maven central repo
├── library
├── robospock
├── sample
├── test-library
├── build.gradle    <--- main build script
└── settings.gradle <--- modules definitions

We’ve introduced following modules:

  • library - heart of the project, packaged to JAR, managed by standard gradle java plugin, provides all the internals of the library like classes for images caching, asynchronous images downloading etc.
  • test-library - built by NBS and its android-library plugin, packaged to AAR (new Android extension for android library projects), acts like a sample app with some layouts to be inflated and tested by Robolectric
  • robospock - guard of the quality contains all RoboSpock specifications (i.e. tests) and other Robolectric related stuff like custom shadow classes
  • sample - Sample Android application with AndroidImageCache, build by NBS and its android plugin, packaged to APK, lets you use and play with the library without building it from the scratch.

Convention over Configuration

NBS breaks (or to putting it politely changes) the current conventions in the layout of Android project. So far, by default the project layout was:

├── AndroidManifest.xml
├── build.xml <--- ANT
├── libs
├── res
│   ├── layout
│   └── values
└── src

In NBS, the default convention is:

├── build.gradle <--- Gradle
└── src
    ├── instrumentTest
    │   └── java
    ├── main
    │   ├── AndroidManifest.xml <--- manifest is no longer in the root folder by default!
    │   ├── assets
    │   ├── java
    │   └── res <--- res also moved to main!
    │       ├── drawable
    │       ├── layout
    │       ├── raw
    │       └── values
    └── release  <--- you can have different res folder for 'release' variant
        └── res

IntelliJ IDEA configuration problems

While the new convention seems to be consistent with general Maven/Gradle convention of src/<scope>/<type> (like src/main/java or src/test/resources) what is definitely a good choice, it no longer works by default in IDE (IntelliJ IDEA at least). If you want to follow new layout in IDEA, you have to manually adjust your module settings like here:

screenshot

Unfortunately, many tools and libraries (like Robolectric) do not yet follow this new convention and by default expect your AndroidManifest.xml and res/ folder to be placed in the root of the project, not under src/main. For example, with Robolectric you can be faced up with the following exceptions:

Caused by: java.io.FileNotFoundException:
/home/mgrzechocinski/dev/polidea/AndroidImageCache/test-library/./AndroidManifest.xml
not found or not a file; it should point to your project's AndroidManifest.xml
	at com.xtremelabs.robolectric.RobolectricConfig.validate(RobolectricConfig.java:70)

or

Caused by: java.io.FileNotFoundException:
/home/mgrzechocinski/dev/polidea/AndroidImageCache/test-library/./res
not found or not a directory; it should point to your project's res directory
	at com.xtremelabs.robolectric.RobolectricConfig.validate(RobolectricConfig.java:74)

However, if you really want to follow the new NBS project layout you can configure Robolectric. Just check customizing page.

Module dependencies nightmare

NBS introduces its own plugins: android and android-library. Unfortunately, they conflicts with the default gradle java plugin and cannot be use both in the same build.gradle. From the NBS documentation:

Important: You should only apply the android plugin. Applying the java plugin as well will result in a build error.

The above leads us to a major dependency nightmare. Suppose you have the RoboSpock or raw Robolectric module, built by standard gradle java plugin which depends on your Android module (build by NBS ‘android’ or ‘android-library’ plugin). RoboSpock module uses R class generated by Android module to bind to components defined in layouts in Android module. It’s not a sophisticated use case. So far, we couldn’t find any simpler and nicer way to set a dependency between those two modules, than extending the source sets to be compiled in RoboSpock module:

def rLocationDir = new File("../test-library/build/source/r/release")
compileJava {
    source rLocationDir
}

Moreover, because NBS uses it’s own ‘android’ and ‘android-library’ plugins, importing project from existing sources is far from perfect. Neither importing as standard Gradle project nor gradle idea seem to properly recognize module dependencies, SDK etc. There’s already a future request for that. It’s still open so do not hesitate to vote for it!

Release and publish to Central Maven repo

Based on SpringFramework sources and nice article by Yennick Trevels we have also setup automatic release and archives upload to Central Maven repository. Latest version is already published, as our second library under pl.polidea groupId :). You can find how to obtain it in project README.

share


MateuszLead Software Engineer

LEARN MORE

Contact us if you have any questions regarding the article or just want to chat about technology, our services, job offers and more!

POLIDEA NEWSLETTER

Sign in and expect sharp insights, recommendations, ebooks and fascinating project stories delivered to your inbox

The controller of the personal data that you are about to provide in the above form will be Polidea sp. z o.o. with its registered office in Warsaw at ul. Przeskok 2, 00-032 Warsaw, KRS number: 0000330954, tel.: 0048 795 536 436, email: hello@polidea.com (“Polidea”). We will process your personal data based on our legitimate interest and/or your consent. Providing your personal data is not obligatory, but necessary for Polidea to respond to you in relation to your question and/or request. If you gave us consent to call you on the telephone, you may revoke the consent at any time by contacting Polidea via telephone or email. You can find detailed information about the processing of your personal data in relation to the above contact form, including your rights relating to the processing, HERE.

Data controller:

The controller of your personal data is Polidea sp. z o.o. with its registered office in Warsaw at ul. Przeskok 2, 00-032 Warsaw, KRS number: 0000330954, tel.: [0048795536436], email: [hello@polidea.com] (“Polidea”)

Purpose and legal bases for processing:

 

Used abbreviations:

GDPR – Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016
on the protection of natural persons with regard to the processing of personal data and on the free movement
of such data, and repealing Directive 95/46/EC (General Data Protection Regulation)

ARES – Polish Act on Rendering Electronic Services dated 18 July 2002

TL – Polish Telecommunications Law dated 16 July 2004

1)        sending to the given email address a newsletter including information on Polidea’s new projects, products, services, organised events and/or general insights from the mobile app business world |art. 6.1 a) GDPR, art. 10.2 ARES and art. 172.1 TL (upon your consent)

Personal data:name, email address

2)       statistical, analytical and reporting purposes |art. 6. 1 f) GDPR (based on legitimate interests pursued by Polidea, consisting in analysing the way our services are used and adjusting them to our clients’ needs, as well as developing new services)

Personal data:name, email address

Withdrawal of consent:

You may withdraw your consent to process your personal data at any time.

Withdrawal of the consent is possible solely in the scope of processing performed based on the consent. Polidea is authorised to process your personal data after you withdraw your consent if it has another legal basis for the processing, for the purposes covered by that legal basis.

Categories of recipients:

Your personal data may be shared with:

1)       authorised employees and/or contractors of Polidea

2)       persons or entities providing particular services to Polidea (accounting, legal, IT, marketing and advertising services) – in the scope required for those persons or entities to provide those services to Polidea

 

Retention period:

1)       For the purpose of sending newsletter to the given email address – for as long as the relevant consent is not withdrawn

2)       For statistical, analytical and reporting purposes – for as long as the relevant consent is not withdrawn

Your rights:

 

Used abbreviation:

GDPR – Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016
on the protection of natural persons with regard to the processing of personal data and on the free movement
of such data, and repealing Directive 95/46/EC (General Data Protection Regulation)

According to GDPR, you have the following rights relating to the processing of your personal data, exercised by contacting Polidea via [e-mail, phone].

1)       to access to your personal data (art. 15 GDPR) by requesting sharing and/or sending a copy of all your personal data processed by Polidea

2)       to request rectification of inaccurate personal data
(art. 16 GDPR) by indicating the data requiring rectification

3)       to request erasure of your persona data (art. 17 GDPR); Polidea has the rights to refuse erasing the personal data in specific circumstances provided by law

4)       to request restriction of processing of your personal data (art. 18 GDPR) by indicating the data which should be restricted

5)       to move your personal data (art. 20 GDPR) by requesting preparation and transfer by Polidea of the personal data that you provided to Polidea to you or another controller in a structured, commonly used machine-readable format

6)       to object to processing your personal data conducted based on art. 6.1 e) or f) GDPR, on grounds relating to your particular situation (art. 21 GDPR)

7)       to lodge a complaint with a supervisory authority,
in particular in the EU member state of your habitual residence, place of work or place of the alleged infringement if you consider that the processing
of personal data relating to you infringes the GDPR
(art. 77.1 GDPR)

No obligation to provide data:

Providing your personal data is not obligatory, but necessary for Polidea to provide you the newsletter service

Refusal to provide the above data will result in inability to receive the newsletter service.

Profiling

In the process of providing the newsletter service, we make decisions in an automated way, including profiling, based on the data you provide.

 

“Profiling” means automated processing of personal data consisting of the use of your personal data to evaluate certain personal aspects relating to you, in particular to analyze or predict aspects concerning your personal preferences and interests.

 

The automated decisions are taken based on the analysis of clicked and viewed content. They affect the targeting of specific newsletter content to selected users registered to receive the newsletter service, based on the anticipated interests of the recipient.