Hands, Soul, and Gradle: The Minimal Android App Setup with Modular Architecture

Introduction

Welcome to "Hands, Soul, and Gradle," a step-by-step guide to setting up a minimal Android project using IntelliJ IDEA and Gradle. This tutorial will walk you through creating a basic project structure, writing the necessary code, and running your first Android application. We'll also show you how to add a UI module to your project, demonstrating a modular approach to Android development. This tutorial is perfect for beginners who want to get started with Android development with the least amount of code and effort.

Prerequisites

Step-by-Step Guide

1. Create a New Project in IntelliJ IDEA

  1. Open IntelliJ IDEA and select New Project.
  2. Choose Android under Templates, then select Phone and Tablet.
  3. Select No Activity and click Next.
  4. Fill in the project details:
    • Name: Bear
    • Package name: com.example.bear
    • Save location: Choose your desired location
    • Language: Kotlin
    • Minimum SDK: API 24 (Nougat)
    • Build Configuration Lang: Kotlin DSL
  5. Click Create to generate the project.
  6. Add a New Module to the Project:
  7. In IntelliJ IDEA, go to File > New > Module.
  8. Choose Android under Templates, then select Phone and Tablet.
  9. Select No Activity and click Next.
  10. Fill in the module details:
    • Module name: ui
    • Package name: com.example.ui
  11. Click Finish to create the module.

2. Project Structure

Your project should have the following structure:

/ProjectRoot
├── build.gradle.kts
├── settings.gradle.kts
└── app
│   ├── build.gradle.kts
│   └── src
│       └── main
│           ├── AndroidManifest.xml
│           ├── java
│           │   └── com
│           │       └── example
│           │           └── bear
│           │               └── MainActivity.kt
│           └── res
│               └── layout
│                   └── activity_main.xml
└── ui
    ├── build.gradle.kts
    └── src
        └── main
            ├── AndroidManifest.xml
            ├── java
            │   └── com
            │       └── example
            │           └── ui
            │               └── ButtonActivity.kt
            └── res
                └── layout
                    └── activity_buttons.xml

3. Generate Necessary Files Using IntelliJ IDEA

3.1. Generate MainActivity.kt

  1. Right-click on the com.example.bear package directory.
  2. Select New -> Kotlin Class/File.
  3. Name the file MainActivity and select Class.
  4. IntelliJ IDEA will generate the MainActivity.kt file.

Add the following code to MainActivity.kt:

package com.example.bear

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.example.ui.ButtonActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = Button(this)
        button.text = "Go to Buttons"
        button.setOnClickListener {
            startActivity(Intent(this, ButtonActivity::class.java))
        }

        val layout = findViewById<LinearLayout>(R.id.mainLayout)
        layout.addView(button)
    }
}

3.2. Generate activity_main.xml

  1. Right-click on the res directory.
  2. Select New -> Android Resource Directory.
  3. Name the directory layout.
  4. Right-click on the new layout directory and select New -> Layout Resource File.
  5. Name the file activity_main.

IntelliJ IDEA will generate the activity_main.xml file. Replace its content with:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/mainLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
</LinearLayout>

3.3. Generate ButtonActivity.kt in the :ui module

  1. Right-click on the com.example.ui package directory.
  2. Select New -> Kotlin Class/File.
  3. Name the file ButtonActivity and select Class.
  4. IntelliJ IDEA will generate the ButtonActivity.kt file.

Add the following code to ButtonActivity.kt:

package com.example.ui

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class ButtonActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_buttons)
    }
}

3.4. Generate activity_buttons.xml in the :ui module

  1. Right-click on the res directory.
  2. Select New -> Android Resource Directory.
  3. Name the directory layout.
  4. Right-click on the new layout directory and select New -> Layout Resource File.
  5. Name the file activity_buttons.

IntelliJ IDEA will generate the activity_buttons.xml file. Replace its content with:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 1" />

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 2" />

</LinearLayout>

4. Configure AndroidManifest.xml Files

4.1. Update AndroidManifest.xml of the :app module
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          >

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.Bear">

        <activity
                android:name=".MainActivity"
                android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>
4.2. Update AndroidManifest.xml of the :ui module
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.ui">

    <application
            android:allowBackup="true"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.Bear">

        <activity
                android:name=".ButtonActivity"
                android:exported="true">
        </activity>

    </application>

</manifest>

5. Gradle Configuration

5.1. Root-level settings.gradle.kts
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "Bear"
include(":app")
include(":ui")
5.2. build.gradle.kts of the :app module
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.nard"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.nard"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {

    implementation("androidx.core:core-ktx:1.13.1")
    implementation("androidx.appcompat:appcompat:1.7.0")
    implementation("com.google.android.material:material:1.12.0")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
    implementation(project(":ui"))
}
5.3. build.gradle.kts of the :ui module
plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.ui"
    compileSdk = 34

    defaultConfig {
        minSdk = 24
        targetSdk = 34

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {

    implementation("androidx.core:core-ktx:1.13.1")
    implementation("androidx.appcompat:appcompat:1.7.0")
    implementation("com.google.android.material:material:1.12.0")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
}

File> sync project with gradle files

6. Build and Run the Project

6.1. Clean and Rebuild the Project

In IntelliJ IDEA, go to Build -> Clean Project to clean the project.
Then go to Build -> Rebuild Project to rebuild the project.

6.2. Run the Project

Press Shift + F10 to run the project.

Conclusion

Congratulations! You've successfully set up a minimal Android project using IntelliJ IDEA and Gradle, with an additional UI module. This modular approach helps in organizing and managing your code better, especially as your project grows. Happy coding!
By following this guide, users can quickly set up a minimal Android project, letting IntelliJ IDEA handle the boilerplate code generation, and focus on the essential parts of the application. Feel free to follow it and let me know if you encounter any issues!