Android-SDK-Setup
Whenever I return to android development after half a year, I need at least one day to get decent versions of all the needed component work nicely together. This time I started from scratch:
- Set ANDROID_HOME to a empty directory
- Download the sdk and only the sdk
unzip -d $ANDROID_HOME ~/Downloads/sdk-tools-darwin/linux-version.zip
- In $ANDROID_HOME run
tools/bin/sdkmanager --licenses
to accept all current licenses - In $ANDROID_HOME run
tools/bin/sdkmanager --update
to bring the tool itself uptodate -
-
In $ANDROID_HOME run
tools/bin/sdkmanager packagenames
to install all needed packages -
For me:
tools/bin/sdkmanager "build-tools;26.0.0" "extras;android;m2repository" "platform-tools" "platforms;android-23"
followed bytools/bin/sdkmanager --uninstall emulator
results in around 750GB of development tools needed for one of my current apps.
-
In $ANDROID_HOME run
- Download the newest intellij (I use the jetbrains toolbox) and start a new android project there
To get the best results I use almost always the latest stable versions. Only take rc's, betas, ... if you know exactly what you are doing. Most of the time you have to update them quite soon.
As all sources are in git, I suggest to use the following scheme to version android. Keep the versions out of AndroidManifest.xml
and put them instead into build.gradle. Manage versionCode
manually (or automate this in a release script), generate versionName
by git describe --dirty
. For git describe to work always, there has to be a tag in the repository. It does not work on a repository without tags.
Minimal snippet of build.gradle to get this working:
...
android {
defaultConfig {
versionCode 2
versionName "git describe --dirty".execute().text.trim();
}
...
I suggest to divide the app into one part purely java and unit test this extensively, and another part that does all the android and ui specific glue code. In the best case this should not be too much on top of the real business logic.
settings.gradle - just pulls in all the modules
include ':lib'
include ':app'
lib/build.gradle - normal java project with 1.7 compatibility
...
sourceCompatibility = 1.7
targetCompatibility = 1.7
...
app/build.gradle This is the most tricky one, I will go through step by step
Android build tools are needed for the buildscript itself (this must be fitting for intellij's and gradle's versions):
...
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
}
apply plugin: 'com.android.application'
...
Pull in your libs:
...
dependencies {
compile ...
annotationProcessor ...
compile project(':lib')
}
...
Because of the separation it is possible to do a lot of work with normal unit-tests. I did not look into android unit-testing in the last years, but it is supposed to be more evolved than to the android 1.0 time. Still I prefer to test as much as possible with normal junit tests. These are my settings for normal java modules:
...
test {
testLogging {
showStandardStreams = true
exceptionFormat = 'full'
}
}
apply plugin: 'jacoco'
jacocoTestReport {
reports {
html.enabled = true
xml.enabled = true
csv.enabled false
}
}
check.dependsOn jacocoTestReport
...
For android modules I have this in place:
...
android {
testOptions.unitTests.all {
testLogging {
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
}
}
...
the gradle android build is very sophisticated in producing different flavors and whatnot of the application. For simple application it is important to know, that you can deploy several versions to the target at the same time (e.g. one debug and one release version). To make it more easy to distinguing between them its possible to do adjustments like this in app/build.gradle:
...
android {
buildTypes {
release {
applicationIdSuffix ".release"
resValue "string", "app_name", "Appname"
}
debug {
applicationIdSuffix ".debug"
resValue "string", "app_name", "Appname-Debug"
}
}
...
Prerequisites:
- Various artwork
- Keystore for signing the apk. I suggest you use the Google Play App Signing. There google creates and keeps a certificate for signing apps that you upload with your upload certificate. In case you loose the upload certificate, you can revoke this and put a new one to google play.
Put the signing into gradle like described on the google page. The only twist I use is to store the password in the keychain/ring:
...
// from http://stackoverflow.com/a/22597752
def passwordFromKeychain = { name ->
return "security find-generic-password -s ${name} -a ${name} -w".execute().text.trim();
}
android {
signingConfigs {
release {
// just add a new password with appname-play-store, appname-play-store and password in keychain on osx
storeFile file("store/release.keystore")
storePassword passwordFromKeychain("appname-play-store")
keyAlias "appname"
keyPassword passwordFromKeychain("appname-play-store")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
...