What's the difference between viewBinding enabled true and buildfeatures viewBinding true - kotlin

What's the difference between the options to enable viewBinding:
viewBinding {
enabled = true
}
AND
Groovy
buildFeatures {
viewBinding true
}
Kotlin
buildFeatures {
viewBinding = true
}

viewBinding {
enabled = true
}
this used to be used and now some users are seeing error
buildFeatures {
viewBinding = true
}
they are using this.
But there is no difference in terms of usage.

Related

how to solve kotlin coroutine annotation warning

let me ask
I use kotlin coroutine
#OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch {
displaySura()
}
and in the build tab showing warning:
This annotation should be used with the compiler argument '-opt-in=kotlin.RequiresOptIn'
how to solve this warning?
thanks in advance
You can add -opt-in=kotlin.RequiresOptIn compiler argument in the build file:
compileKotlin {
kotlinOptions {
freeCompilerArgs += [
"-Xopt-in=kotlin.RequiresOptIn"
]
}
}
To clarify to #Sergio's answer, you can add the block here in your app's build.gradle file
android {
kotlinOptions {
jvmTarget = '1.8'
freeCompilerArgs += [
"-Xopt-in=kotlin.RequiresOptIn"
]
}

Jetpackcompose 1.1.1. Modifier.align doens't exist anymore

I have upgrade my projet to jetpack compose 1.1.1, together with Kotlin 1.6.10 and 7.1.2 upgrade of datastudio.
From then, Android studio throws an error when trying to use Modifier.align(..).
I checked the release notes of jpc, and can't find any information that align() is depreciated.
Can't understand what is wrong here
without .align, the project is buidling fine, but I can no longer align a button at the botton of the screen :-(
my projet build.gradle
buildscript {
ext {
compose_version = '1.1.1'
nav_version = "2.4.1"
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
my Module build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.jerome.jetpackcomposecrashcourse"
minSdk 29
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled 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'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
// navigation
implementation "androidx.navigation:navigation-compose:$nav_version"
}
the composable taht was fine before but now throwing error
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
#Composable()
fun AddAlbumButton() {
val mainButtonColor = ButtonDefaults.buttonColors(backgroundColor = Color(247, 197, 33))
Button(
colors = mainButtonColor,
modifier = Modifier
.padding(24.dp)
.align(Alignment.BottomCenter) // <----- ERROR HERE
,
onClick = {
/*albums.add(
Album(
R.drawable.booksouls,
"book of souls",
"View details",
Font(R.font.font_book_of_souls, weight = FontWeight.ExtraBold),
fontSize = 16.sp
)
)*/
}
) {
Text(text = "Add one")
}
}
I just tried your code with Jetpack Compose 1.0.1 version and it didn't work there too. You can wrap your button inside Column, Row or Box.
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.BottomCenter
) {
Button(
modifier = Modifier
.padding(24.dp),
onClick = {
}
) {
Text(text = "Add one")
}
}

How to add coverage report (JaCoCo) to kotest based using build.gradle.kts?

I use Kotlin for server side, and I want to add test coverage (by using JaCoCo but can be any other open source).
At the moment, I don't find any documentation to explain how to enable/add coverage report to kotlin project based on kotest which actually works.
(Yes I tried the official documentation)
build.gradle.kts:
import Libraries.coroutines
import Libraries.koTest
import Libraries.koTestCore
import Libraries.mockk
import Libraries.testcontainers
import Libraries.testcontainersPostgres
plugins {
java
`kotlin-dsl` version "1.3.5" apply false
kotlin("jvm") version Versions.kotlin_version
kotlin("plugin.serialization") version Versions.kotlin_version apply false
id("com.diffplug.gradle.spotless") version Plugins.spotless
id("com.palantir.docker") version Plugins.docker apply false
id("com.palantir.docker-run") version Plugins.docker apply false
id("com.google.protobuf") version Plugins.protobuf apply false
id("org.flywaydb.flyway") version Plugins.flyway apply false
}
allprojects {
group = "my-app"
version = "2.0"
apply(plugin = "kotlin")
apply(plugin = "com.diffplug.gradle.spotless")
repositories {
mavenCentral()
jcenter()
}
tasks {
compileKotlin {
dependsOn(spotlessApply)
kotlinOptions {
jvmTarget = "11"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "11"
}
}
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
tasks.withType<Test> {
useJUnitPlatform()
maxParallelForks = 1
environment("ENV", "test")
}
afterEvaluate {
project.configurations.forEach {
// Workaround the Gradle bug resolving multiplatform dependencies.
if (it.name.contains("Proto")) {
it.attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, Usage.JAVA_RUNTIME))
}
}
}
}
subprojects {
spotless {
kotlin {
ktlint().userData(mapOf("disabled_rules" to "no-wildcard-imports"))
trimTrailingWhitespace()
endWithNewline()
}
}
dependencies {
implementation(coroutines)
testImplementation(koTest)
testImplementation(koTestCore)
testImplementation(mockk)
testImplementation(testcontainers)
testImplementation(testcontainersPostgres)
}
configurations {
all {
resolutionStrategy.setForcedModules("org.apache.httpcomponents:httpclient:4.5.9")
}
}
}
Any help will be great. Thanks in advance.
in my experience, Jacoco and Kotest interoperate just fine out of the box. I'm using it and all I need to do is the following:
plugins {
jacoco
// The rest of your plugins
}
// Your build, as it was before
You can inspect a working Jacoco + Kotest build here.
To verify that it works, you can e.g., feed the Jacoco generated data to services such as Codecov.io.
First, generate the report in XML format:
tasks.jacocoTestReport {
reports {
xml.isEnabled = true
}
}
And then use the Codecov.io service to fetch and analyze the results:
bash <(curl -s https://codecov.io/bash)
As you can see in this report, Jacoco is doing its job without further configuration.

Task :transformClassesAndResourcesWithR8ForRelease FAILED Program type already present *.BuildConfig

I have an Android Studio (3.4.1) cocos2d-x project with multiple modules. My settings.gradle file defines the 3 modules:
include ':libcocos2dx'
project(':libcocos2dx').projectDir = new File(settingsDir, '../cocos2d/cocos/platform/android/libcocos2dx')
include ':ToaTetrisApp'
project(':ToaTetrisApp').projectDir = new File(settingsDir, 'app')
include ':gameCircleSDK'
NOTE: gameCircleSDK does not need its projectDir set because the directory matches the module name inside proj.android
The problem I have is that when I build a release build of the application OR I try to Build->Generate Signed Bundle / APK I get the following error:
>Task :ToaTetrisApp:transformClassesAndResourcesWithR8ForRelease FAILED
AGPBI: {"kind":"error","text":"Program type already present: com.amazon.ags.BuildConfig","sources":[{}],"tool":"D8"}
NOTE: com.amazon.ags.BuildConfig is an auto-generated class for the gameCircleSDK module. The AndroidManifest.xml for gameCircleSDK defines package="com.amazon.ags" and this is the only place that the package is defined.
I also searched my generated files and found only the expected BuildConfig.java files in the release folders: com.toa.tetris (ToaTetrisApp), com.amazon.ags (gameCircleSDK), org.cocos2dx.lib (cocos2d-x)
I have the following build.gradle files:
proj.android:build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
buildDir = "C:/tmp/${rootProject.name}/${project.name}"
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
proj.android:app:build.gradle [ToaTetrisApp]
import org.gradle.internal.os.OperatingSystem
apply plugin: 'com.android.application'
android {
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
defaultConfig {
applicationId "com.toa.tetris"
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION
versionCode 21
versionName "4.5.1"
multiDexEnabled true
externalNativeBuild {
if (PROP_BUILD_TYPE == 'ndk-build') {
ndkBuild {
targets 'MyGame'
arguments 'NDK_TOOLCHAIN_VERSION=clang'
//arguments 'V=1'
arguments '-j' + Runtime.runtime.availableProcessors()
def module_paths = [project.file("../../cocos2d").absolutePath,
project.file("../../cocos2d/cocos").absolutePath,
project.file("../../cocos2d/external").absolutePath]
if (OperatingSystem.current().isWindows()) {
module_paths = module_paths.collect {it.replaceAll('\\\\', '/')}
arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
}
else {
arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
}
}
}
else if (PROP_BUILD_TYPE == 'cmake') {
cmake {
targets 'MyGame'
arguments "-DCMAKE_FIND_ROOT_PATH=", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE"
cppFlags "-frtti -fexceptions -fsigned-char"
}
}
}
ndk {
abiFilters = []
abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
}
}
sourceSets.main {
java.srcDir "src"
res.srcDir "res"
manifest.srcFile "AndroidManifest.xml"
assets.srcDir "../../Resources"
}
externalNativeBuild {
if (PROP_BUILD_TYPE == 'ndk-build') {
ndkBuild {
path "jni/Android.mk"
}
}
else if (PROP_BUILD_TYPE == 'cmake') {
cmake {
path "../../CMakeLists.txt"
}
}
}
signingConfigs {
release {
<CONTENT REMOVED>
}
debug {
<CONTENT REMOVED>
}
}
buildTypes {
release {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.release
}
externalNativeBuild {
ndkBuild {
arguments 'NDK_DEBUG=0'
}
}
}
debug {
debuggable true
jniDebuggable true
renderscriptDebuggable true
externalNativeBuild {
ndkBuild {
arguments 'NDK_DEBUG=1'
}
}
}
}
}
android.applicationVariants.all { variant ->
// delete previous files first
delete "${buildDir}/intermediates/assets/${variant.dirName}"
variant.mergeAssetsProvider.get().doLast {
copy {
from "${buildDir}/../../../Resources"
into "${buildDir}/intermediates/assets/${variant.dirName}"
exclude "**/*.gz"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(dir: '../gameCircleSDK/libs', include:['*.jar'])
implementation project(':libcocos2dx')
implementation project(':gameCircleSDK')
}
proj.android:gameCircleSDK:build.gradle
apply plugin: 'com.android.library'
android {
signingConfigs {
debug {
<CONTENT REMOVED>
}
}
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
//buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION
}
sourceSets.main {
manifest.srcFile "src/main/AndroidManifest.xml"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
}
proj.android:..:cocos2d:cocos:platform:android:libcocos2dx:build.gradle
apply plugin: 'com.android.library'
android {
signingConfigs {
debug {
<CONTENT REMOVED>
}
}
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
defaultConfig {
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION
versionCode 1
versionName "1.0"
}
sourceSets.main {
aidl.srcDir "../java/src"
java.srcDir "../java/src"
manifest.srcFile "AndroidManifest.xml"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: '../java/libs', include: ['*.jar'])
}
I have been searching and found many recommendations and tried many of them to no avail. Here are some of the things I've tried:
I tried File->Invalidate Caches / Restart: NOTE: I originally had the same problem with my debug build and run and this is the solution that resolved that issue.
I have tried running 'gradlew ToaTetrisApp:dependencies' and I don't see any reference to com.amazon.ags nor any duplicates. I'm not sure I fully understand the output, but it seems for the debug, release and tests the dependencies seem to be as expected
I have, of course, tried to clean and rebuild many times, but to no avail
I have added 'multiDexEnabled true' to my app:build.gradle file. I'm not sure whether this really did anything or whether I added it to the correct file. This didn't seem to resolve the issue
I have tried to add 'afterEvaluate { generateReleaseBuildConfig.enabled = false }', but again, I wasn't sure which build.gradle to add this to so I couldn't get it to work
I'm hoping that someone can provide some explanation of what exactly this error means and how I can track down and resolve this issue myself. This project doesn't use a lot of external dependencies so I would expect that it would be easy to track down what is going on exactly and why this error shows up. If you would like to offer some suggestions then please let me know which gradle file you would like me to add the code to as that is often not mentioned.

Receiving form params to Ktor server

I'm new to Java and Kotlin, trying to build a contact form with Ktor, so I enabled the insecure connection of my gmail from here, and built the app below:
blogApp.kt:
package blog
import org.jetbrains.ktor.netty.*
import org.jetbrains.ktor.routing.*
import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.features.*
import org.jetbrains.ktor.host.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.response.*
import org.apache.commons.mail.*
fun Application.module() {
install(DefaultHeaders)
install(CallLogging)
install(Routing) {
get("/") {
call.respondText("""
My Example Blog2
<form action="/contact-us" method="post">
<input name="subject" placeholder="Subject">
<br>
<textarea name="message" placeholder="Your message ..."></textarea>
<br>
<button>Submit</button>
</form>
""", ContentType.Text.Html)
}
post("/contact-us") {
SimpleEmail().apply {
setHostName("smtp.gmail.com")
setSmtpPort(465)
setAuthenticator(DefaultAuthenticator("my_alias#gmail.com", "my_gmil_passoword"))
setSSLOnConnect(true)
setFrom("my_alias#gmail.com")
setSubject("subject") // I need to use formParam
setMsg("message") // I need to use formParam
addTo("my_alias#gmail.com")
}.send() // will throw email-exception if something is wrong
call.respondRedirect("/contact-us/success")
}
get("/contact-us/success") {
call.respondText("Your message was sent", ContentType.Text.Html)
}
}
}
fun main(args: Array<String>) {
embeddedServer(Netty, 8080, watchPaths = listOf("BlogAppKt"), module = Application::module).start()
}
build.gradle:
group 'Example'
version 'alpha'
buildscript {
ext.kotlin_version = '1.1.4-3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
ext.ktor_version = '0.4.0'
repositories {
mavenCentral()
maven { url "http://dl.bintray.com/kotlin/ktor" }
maven { url "https://dl.bintray.com/kotlin/kotlinx" }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.ktor:ktor-core:$ktor_version"
compile "org.jetbrains.ktor:ktor-netty:$ktor_version"
compile "org.apache.commons:commons-email:1.4"
compile "org.slf4j:slf4j-simple:1.7.25"
compile "ch.qos.logback:logback-classic:1.2.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
kotlin {
experimental {
coroutines "enable"
}
}
jar {
baseName 'abc'
manifest {
attributes 'Main-Class': 'blog.BlogAppKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
and things gone smoothly with it, I was able to send an email to myself then redirect to the success page, but the message got sent is with pre-set data:
setSubject("subject") // I need to use formParam
setMsg("message") // I need to use formParam
how can I make the Ktor receive the data the user really entered in the form, how can I read the form params?
You can use call.receive<ValuesMap>() and introspect the data:
import org.jetbrains.ktor.request.* // for recieve
import org.jetbrains.ktor.util.* // for ValuesMap
post("/contact-us") {
val post = call.receive<ValuesMap>()
val subj = post["subject"]
val msg = post["message"]
SimpleEmail().apply { ... }
}
NOTE: ValuesMap is deprecated in latest ktor version, so use the following code:
val post = call.receiveParameters()
Well although the above answer would have been correct at that point of time, today when I am going through kotlin + Ktor, I see that the above answer is not valid anymore.
What you need now is something like this:
call.receive< Parameters >()["PARAM_NAME"]
Parameters class is in the following package: io.ktor.http.Parameters
Nikhil