here's my `build.gradle`
# kotlin-native
d
here's my
build.gradle
r
This build file does not support Android. Creating a
jvm
target and naming it
android
does not make it an
android
target. Use the
android
preset, the android plugin and have a proper android block.
You usually do what you did when you actually don’t need Android platform APIs, this way you can publish your library as a JVM library and it’s simpler to build, deploy and use.
If you need Android APIs, then you’re doing an actual Android library (
.aar
file) or an Android application (
.apk
file)
d
got it. i took that line (
fromPreset(presets.jvm, 'android')
) straight from the "Multiplatform Project: iOS and Android" tutorial
the tutorial demonstrates using
platform.UIKit
, so i assumed it was nearly demonstrating how to use
platform.android
. but i guess it is still a bit far from demonstrating
platform.android
use.
r
Yes but this tutorial is for creating a library used by native applications. There’s a whole spectrum of multiplatform usage you can have. Your entire app could be multiplatform
platform.*
is a native thing. Android isn’t native (or at least that’s not what you want). To clarify, there’s no
platform.android
. You would just import Android APIs normally like in a normal Android project
d
i swear i saw
import platform.android.*
in a couple examples
i'm not really sure what i want. right now, instead of calling into android APIs from my native library, since i couldn't figure that out, i am declaring `interface`es in the native library, and having the host application pass in things that adhere to those interfaces, that perform that Android SDK stuff
seems like figuring out how to use `expects`/`actual` might save some lines of code and some OOP headaches
but i'm not sure
r
Well there is a
platform.android
, but for Android Native development, which is a very different thing
d
like NDK?
r
Yes
d
got it
r
Usually you would use `expect`/`actual` yeah.
d
so i just need like
apply plugin("com.android.library")
and an
android { }
block?
in build.gradle?
r
did you manage to make your
android
target work? An Android target is surprisingly harder to setup than a native one because you have to setup the whole android library thing
Basically yes, and change the preset you use
d
my android app is running and it is using the kotlin multiplatform lib
r
Also you can just do
android()
instead of some fromPreset thing
d
or is it kotlin native lib... dunno what's the difference between multiplatform / native, if any
(also my iOS app is running and is using the lib) *i think, lol
r
Kotlin Native is for Native development only (Which still covers iOS, Linux, Windows, etc, all native). Multiplatform is “Kotlin everywhere”, including JVM, JS, Android
But you can (and should, I think) use the multiplatform plugin when developing just for iOS. That’s what I do. This way you just get used to one way to make build files for any platform
d
i'm developing a lib that should have an Android flavor and an iOS flavor
the iOS flavor is output as a .framework and it is able to call into iOS platform APIs
the Android flavor is outputting as an Android lib and it works, but i'm not yet able to call Android platform APIs
r
If you’re used to make android build files then doing the Android part should be dead simple
d
i am totally not used to making android anything
r
That’s just because your “Android lib” was actually just a Java lib
d
ok
does any of this seem very hard or impossible? do i just need to edit my build.gradle file correctly?
r
Here is a basic android block in the build file of one of my libs
Copy code
android {

    compileSdkVersion(Versions.androidCompileSdk)

    defaultConfig {
        minSdkVersion(Versions.androidMinSdk)
        targetSdkVersion(Versions.androidTargetSdk)
        versionName = Versions.appVersionName
        versionCode = Versions.appVersionCode
    }

    sourceSets {
        getByName("main") {
            setRoot("src/androidMain")
        }
        getByName("test") {
            setRoot("src/androidTest")
        }
    }

    lintOptions {
        isAbortOnError = false
    }

}
Just replace your jvm target with an android one and add the block above and it should just work
Note: the android block should come before the kotlin block
The android target expects the android plugin to be configured already
d
ok will try.... (btw, how do you define Versions? i would like to share that info with my app build.gradle)
r
I’m using buildSrc, let’s see if I can find a tutorial on that
You’ll also need to define your android target like this if you want to enable publication, android artifactds aren’t published by default
Copy code
android {
        publishAllLibraryVariants()
    }
(You can customize which variants are published, but if you only got release and debug variants, that works)
d
i don't want to publish
r
Oh, I didn’t see but you’re using Groovy. The code I shown is written in Kotlin, you may need to adapt some stuff.
d
getByName("main")
.... what does
"main"
refer to?
should i have something called
main
somewhere?
i have folders
src/commonMain/kotlin
,
src/androidMain/kotlin
, and
src/iosMain/kotlin
r
No, it’s the default names. You don’t seem used to the Java world, but in this world the concept of “convention over configuration” is abused a lot.
In Groovy you can replace
getByName("main")
with just
main
The entire idea of the
sourceSets
block in the
android
block is to just change
main
to
androidMain
, at least for the sourceSet location
d
ok so it complains there is no AndroidManifest.xml in
androidMain/
i will add one... without an <application> inside...?
sorry this is going pretty deep on my Android noviceness
r
Yeah by convention this file needs to exist even if it’s useless. Welcome to Android 😛 Here’s one of mine for example:
Copy code
<?xml version="1.0" encoding="utf-8"?>
<manifest package="yourpackage" />
Well it’s not entirely useless, your lib may need to define some meta values, ask for some permissions, I don’t know...
d
it builds!
awesome, it looks like i can use
import android.
.... stuff now
thank you!
👍 1