Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Android Studio - Var is seen as val in SDK 29

Tags:

android

kotlin

I'm experiencing a pretty strange thing in Kotlin. I have

var myClipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager? var myClip: ClipData? = ClipData.newPlainText( /* my code */ ) 

As a var variable, I should be able to reassign his value, but when I do

myClipboard?.primaryClip = myClip 

It gives me the error

Val cannot be reassigned

The strangest things is that I'm using this code by weeks and it always worked. It stopped working today when I updated to API 29

This is my build.gradle android{}

    android {     compileSdkVersion 29     defaultConfig {         applicationId "com.arfmann.pushnotes"         minSdkVersion 23         targetSdkVersion 29         versionCode 16         versionName "1.6"         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"     }     buildTypes {         release {             minifyEnabled true             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'         }     } } 
like image 565
Arfmann Avatar asked Jul 20 '19 21:07

Arfmann


People also ask

What is Val and VAR in Kotlin?

A variable declared with `var` is mutable. A variable declared with `val` is immutable. A variable declared with `const` is immutable. Values are assigned at run time. Values are assigned at run time.

What is the difference between VAR and Val in Kotlin by example?

Read-only local variables are defined using the keyword val . They can be assigned a value only once. Variables that can be reassigned use the var keyword. You can declare variables at the top level.

How do I assign a Val in Kotlin?

Kotlin uses two different keywords to declare variables: val and var . Use val for a variable whose value never changes. You can't reassign a value to a variable that was declared using val . Use var for a variable whose value can change.

Why is Val preferred in Kotlin?

Kotlin, the language itself, encourages developers to write immutably, by encouraging you to use val . The result is code that literally looks cleaner. Using vals in your code makes you think about alternative, immutable, functional code.


1 Answers

As seen in the ClipboardManager documentation, getPrimaryClip returns a ClipData? (i.e., a nullable ClipData) while setPrimaryClip() takes a ClipData - a non-null ClipData.

Kotlin does not support var property access when the types are different (and nullability is an important part of Kotlin typing) therefore Kotlin can only give you effectively the val equivalent when you call primaryClip.

The nullability annotation on setPrimaryClip was added in API 29, which is why the behavior is different once you upgrade your compileSdkVersion.

To set the primary clip, you must explicitly use setPrimaryClip() with a non-null ClipData or, on API 28+, use clearPrimaryClip() to completely clear the primary clip.

like image 166
ianhanniballake Avatar answered Sep 23 '22 18:09

ianhanniballake