Skip to content

Commit

Permalink
Hello world Kotlin Jetpack Compose Example; Fixes:com-lihaoyi#3550
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshumahajan138 committed Oct 18, 2024
1 parent 50eb241 commit 103b7b8
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.helloworld.app">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="35"/>
<application android:label="Hello World" android:debuggable="true">
<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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.helloworld.app

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Greeting("Hello, World!")
}
}
}

@Composable
fun Greeting(name: String) {
Text(text = name)
}
45 changes: 45 additions & 0 deletions example/kotlinlib/android/2-jetpack-compose-hello-world/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//// SNIPPET:BUILD
package build

import mill._
import kotlinlib._
import coursier.maven.MavenRepository
import mill.kotlinlib.android.AndroidAppKotlinModule
import mill.javalib.android.AndroidSdkModule

val maven_google = Seq(
MavenRepository("https://maven.google.com/"),
MavenRepository("https://repo1.maven.org/maven2")
)

object androidSdkModule0 extends AndroidSdkModule {
def buildToolsVersion = "35.0.0"
}

object app extends AndroidAppKotlinModule {
def kotlinVersion = "2.0.20"
def androidSdkModule = mill.define.ModuleRef(androidSdkModule0)

override def mandatoryIvyDeps: T[Agg[Dep]] = Task {
super.mandatoryIvyDeps() ++ Agg(
// Jetpack Compose dependencies
ivy"androidx.compose.compiler:compiler:1.5.15",
ivy"androidx.activity:activity:1.8.2",
ivy"androidx.activity:activity-compose:1.8.2",
ivy"androidx.compose.runtime:runtime:1.3.1",
ivy"androidx.compose.material3:material3:1.0.1"
)
}

def repositoriesTask = T.task { super.repositoriesTask() ++ maven_google }

}

////SNIPPET:END

/** Usage

> ./mill show app.androidApk
".../out/app/androidApk.dest/app.apk"

*/
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package mill.kotlinlib.android

import mill.kotlinlib.KotlinModule
import mill.javalib.android.AndroidAppModule
import mill._
import coursier.Type
import upickle.default.ReadWriter

/**
* Trait for building Android applications using the Mill build tool.
Expand All @@ -18,4 +21,66 @@ import mill.javalib.android.AndroidAppModule
* [[https://developer.android.com/studio Android Studio Documentation]]
*/
@mill.api.experimental
trait AndroidAppKotlinModule extends AndroidAppModule with KotlinModule {}
trait AndroidAppKotlinModule extends AndroidAppModule with KotlinModule {

/**
* Implicit `ReadWriter` for serializing and deserializing `coursier.Type` values.
* Converts a `coursier.Type` to a `String` and vice versa.
*/
implicit val coursierTypeRW: ReadWriter[Type] = upickle.default.readwriter[String].bimap(
_.value, // Serialize coursier.Type to String
Type(_) // Deserialize String to coursier.Type
)

/**
* Implicit `ReadWriter` for handling `Set[coursier.Type]`, allowing conversion
* between a set of `coursier.Type` and a set of `String`.
*/
implicit val coursierTypeSetRW: ReadWriter[Set[Type]] =
upickle.default.readwriter[Set[String]].bimap(
_.map(_.value), // Serialize Set[coursier.Type] to Set[String]
_.map(Type(_)) // Deserialize Set[String] to Set[coursier.Type]
)

/**
* Adds the "aar" type to the set of artifact types handled by this module.
*
* @return A task that yields an updated set of artifact types including "aar".
*/
override def artifactTypes: T[Set[Type]] =
T { super.artifactTypes() + coursier.Type("aar") }

/**
* Task to extract `classes.jar` files from AAR files in the classpath.
*
* @return A sequence of `PathRef` pointing to the extracted JAR files.
*/
def recompileAARs: T[Seq[PathRef]] = Task {
val aarFiles = super.compileClasspath().map(_.path).filter(_.ext == "aar").toSeq

aarFiles.map { aarFile =>
val extractDir = T.dest / aarFile.baseName
os.call(Seq("unzip", aarFile.toString, "-d", extractDir.toString))
PathRef(extractDir / "classes.jar")
}
}

/**
* Updates the compile classpath by removing `.aar` files and including the
* extracted `.jar` files from the AARs.
*
* @return A task yielding the updated classpath with `.jar` files.
*/
def updatedCompileClasspath: T[Agg[PathRef]] = Task {
super.compileClasspath().filter(_.path.ext == "jar") ++ Agg.from(recompileAARs())
}

/**
* Overrides the compile classpath to replace `.aar` files with the extracted
* `.jar` files.
*
* @return The updated classpath with `.jar` files only.
*/
override def compileClasspath: T[Agg[PathRef]] = updatedCompileClasspath()

}

0 comments on commit 103b7b8

Please sign in to comment.