The Social Project: Configurando o Tema e Identificando suas Builds

Padrão

Se você ainda não conhece as motivações deste projeto, leia o primeiro artigo aqui.

Olá pessoal! No último post configuramos o Firebase no projeto, ao mesmo tempo em que mantivemos os JSONs de configuração seguros no nosso CI. Hoje vamos começar a preparar nosso app para soltar as primeiras releases.

Trazendo para o projeto algumas experiẽncias que tive em projetos que participei, posso dizer que a diferenciação entre o app em tempo de desenvolvimento e as releases é um problema bastante menosprezado quando estamos trabalhando em um projeto. É muito comum chegarmos ao ponto de não saber ao certo qual é a versão que estamos utilizando, e a inconsistência de comportamento acaba por nos colocar em situações complicadas (como testar o app errado, inconsistência de dados, dentre vários outros).

O primeiro passo, a viabilidade de que tanto as builds de release quanto as de debug possam conviver harmônicamente no mesmo device já foi resolvido no post anterior, através do applicationIdSuffix para o build type de debug.

O que faremos agora é criar uma identidade visual diferente para cada um dos build types.

Aqui vai um aviso: como ainda não temos um design definitivo, ou uma identidade visual para o nosso aplicativo, vai ser algo meio grotesco mesmo, mais como um placeholder do que algo definitivo, ou apropriado para um produto final 🙂

Como ícone do aplicativo, utilizei um dos ícones do banco de ícones do Material Design. São ícones para os mais diversos propósitos, divididos em várias categorias, otimizados tanto para mobile quanto para web.

Sim. Esse é o ícone do nosso app! 😂

Para prosseguirmos, também utilizei a ferramenta de cores do site do Material Design, que me ajudou a encontrar uma combinação de cores com bom contraste e gerar as suas variações mais clara e mais escura. Assim, os nosso ícones ficaram:

Sendo o ícone da esquerda a versão do aplicativo de release e a versão da direita a versão do app de debug.

Aqui, basicamente a ideia foi inverter as cores primary e accent para cada um dos build types. Dessa forma, o aplicativo final terá o verde como primary e o laranja como accent, enquanto a versão de debug terá o laranja como primary e o verde como accent. (vamos ver como isso vai ficar ao longo do projeto – designers, me salvem aqui! 😂)

Para que essa façanha funcione no aplicativo, precisamos fazer uso das diferentes pastas de source. Como pode ser visto no repositório, basicamente eu dupliquei os resources relacionados ao tema e ao ícone, separando suas respectivas versões em src/debug/ressrc/release/res. É importante salientar que os resources devem sempre ter o mesmo nome e os mesmos atributos nos XMLs para as duas pastas, caso contrário teremos problemas ao compilar o aplicativo.

O Android Gradle Plugin (AGP) tem esse mecanismo bacana. Com o mecanismo de build types (e flavors), conseguimos criar variações de um mesmo app facilmente. Da forma como fizemos, o aplicativo de debug será criado mesclando o conteúdo de src/mainsrc/debug, enquanto o de release será criado com o conteúdo de src/mainsrc/release.

Bom, aproveitando, também atualizei algumas coisas no repositório, como o Kotlin para a versão 1.2.31, e o Google Play Services (e Firebase) para a versão 12.0.1. Também atualizei o AGP para a versão 3.1.0, dando suporte ao Android Studio 3.1.

Com isso, tanto nosso app em debug e em release podem conviver em harmonia dentro do mesmo dispositivo.

E é isso! Lembrando que o código já foi mergeado e está disponível na branch develop do projeto.

Até a próxima!

The Social Project: Configurando Kotlin no projeto

Padrão

Olá pessoal!

Se você ainda não conhece as motivações deste projeto, leia o primeiro artigo aqui.

No último post, configuramos o CircleCI para observar as branches do nosso projeto, bem como a abertura de pull requests no repositório. Hoje, vamos olhar um pouco mais o projeto e começar a estruturá-lo para posteriormente iniciarmos a implementação de fato.

O projeto em si foi criado a partir do template padrão do Android Studio 3.0.1, sem qualquer modificação na sua estrutura, e sem a inclusão do Kotlin por padrão. Meu intuito é entendermos o que é necessário para transformarmos um projeto Android com Java em um projeto Android com Kotlin.

O primeiro passo aqui é ajustar o arquivo build.gradle principal, aquele localizado na raiz do projeto. Inicialmente, vamos remover os comentários vindos do template. Eles são informativos sobre como configurar as dependências do projeto, porém podemos removê-los tranquilamente, já que sabemos onde vamos colocar cada coisa.

Em seguida, vamos criar uma variável, chamada de kotlinVersion, para guardar a versão do Kotlin que estaremos utilizando no projeto. É importante que essa versão esteja separada, pois ela deve ser a mesma em todas as dependências relacionadas ao Kotlin no projeto. Aqui fica uma ressalva: perceba que utilizamos a nomenclatura com Camel Case (enquanto o template do AS para Kotlin utiliza Snake Case). O Groovy (linguagem utilizada nos scripts do Gradle) tem convenções de código muito semelhantes ao Java. Assim, utilizamos Snake Case apenas nos casos onde o valor é uma constante, e sempre em caixa alta.

Após isso, adicionamos o plugin de Kotlin para Gradle, fazendo uso da interpolação de strings para inserir a versão. Assim, nosso arquivo build.gradle ficará assim:

buildscript {

    ext.kotlinVersion = '1.2.30'
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Vamos agora editar então o arquivo de build do módulo app (localizado em app/build.gradle). Nele, primeiramente aplicamos o plugin do Kotlin, seguindo a nomenclatura mais recomendada pelo Gradle – utilizando o namespace. Dessa forma, aplicamos o plugin org.jetbrains.kotlin.android. Em seguida, vamos atualizar o tooling para a última versão do Android (atualmente a API 27). Como o Android Studio 3.0 já foi lançado a algum tempo, o seu template padrão ainda aponta para a API 26. Assim, apontamos as versões de compileSdkVersiontargetSdkVersion para 27, além de atualizarmos a versão da Support Library para 27.1.0, a versão mais recente neste momento.

O próximo passo para completar a integração do Kotlin no projeto é a adição da standard library do Kotlin. Essa dependência possui 3 versões: kotlin-stdlib (Java 6), kotlin-stdlib-jre7 (Java 7) e kotlin-stdlib-jre8 (Java 8). Particularmente eu adiciono a versão jre7, primeiro pelo fato da nossa API mínima ser KitKat (que já suporta as features do Java 7). Poderíamos utilizar a jre8, porém isso faria com que o processo de desugaring ocorresse durante a compilação, o que pode impactar no nosso tempo de build.

Por fim, dois pontos de ajuste que particularmente recomendo por questões de organização. O primeiro é a adição de source sets específicos para Kotlin. Quando temos um projeto Java, os arquivos fonte geralmente ficam na pasta src/main/java. Assim, adicionamos aos source sets src/main/kotlin. Ao meu ver, essa organização é particularmente útil quando o projeto acaba tendo arquivos de ambas as linguagens (o que não deve ocorrer no nosso caso) e para que a estrutura de diretórios fique mais semântica. O segundo ponto de ajuste, mais estético, é a padronização do uso de aspas simples e duplas no arquivo. Aspas duplas, somente quando houver interpolação na string.

Nosso arquivo, então, fica dessa forma:

apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'

android {
    compileSdkVersion 27

    defaultConfig {
        applicationId 'net.rafaeltoledo.social'
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName '1.0'

        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        test.java.srcDirs += 'src/test/kotlin'
        androidTest.java.srcDirs += 'src/androidTest/kotlin'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.0'

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion"

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

Aproveitando que estamos modificando as configurações de build do nosso projeto, recomendo atualizarmos também a versão do Gradle que está sendo utilizada. Para isso, basta gerarmos o wrapper apontando para a versão mais recente (4.6 no momento em que escrevo este post). A não ser quando há imcompatibilidades entre o plugin do Android e o Gradle, sempre recomendo a utilização da versão mais recente do Gradle, já que ela costuma trazer melhorias importantes de performance (o que é sempre bem-vindo). Para atualizar o wrapper, basta executar o seguinte comando:

./gradlew wrapper --gradle-version 4.6 --distribution-type all

Para que nosso aplicativo já tenha uma Activity inicial, também adicionei uma MainActivity vazia e adicionei ao Android Manifest. Também aproveitei e exclui os testes que vem por padrão no template do Android Studio – assim que começarmos a entrar nas features do app, escreveremos os nossos 🙂

Seguindo o nosso Git Flow, criei um Pull Request para a branch develop, que, assim que passou no CI, foi mergeado 🙂

Por hoje é isso. Apesar deste post não mostrar nada muito novo, acho importante configurarmos o Kotlin por nós mesmos e saber o que muda no projeto. Afinal, os build scripts também são código, e mantê-los organizados faz parte da saúde do projeto. Aguardem que no próximo post teremos mais coisas interessantes.

Até lá!