0.4 C
New York
Thursday, November 30, 2023

Information in Android Studio Flamingo


Posted by means of Clément Béra, Senior device engineer

Information are a brand new Java characteristic for immutable information provider categories offered in Java 16 and Android 14. To make use of data in Android Studio Flamingo, you want an Android 14 (API degree 34) SDK so the java.lang.File elegance is in android.jar. That is to be had from the “Android UpsideDownCake Preview” SDK revision 4. Information are necessarily categories with immutable houses and implicit hashCode, equals, and toString strategies in keeping with the underlying information fields. In that recognize they’re similar to Kotlin information categories. To claim a Individual report with the fields String title and int age to be compiled to a Java report, use the next code:

information elegance Individual(val title: String, val age: Int)

The construct.gradle report additionally must be prolonged to make use of the proper SDK and Java supply and goal. These days the Android UpsideDownCake Preview is needed, but if the Android 14 ultimate SDK is launched use “compileSdk 34” and “targetSdk 34” instead of the preview model.

android {
compileSdkPreview "UpsideDownCake"

defaultConfig {
targetSdkPreview "UpsideDownCake"

compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
kotlinOptions {
jvmTarget = '17'

Information don’t essentially convey price in comparison to information categories in natural Kotlin methods, however they let Kotlin methods have interaction with Java libraries whose APIs come with data. For Java programmers this permits Java code to make use of data. Use the next code to claim the similar report in Java:

public report Individual(String title, int age) {}

But even so the report flags and attributes, the report Individual is more or less an identical to the next elegance described the use of Kotlin supply:

elegance PersonEquivalent(val title: String, val age: Int) {

override amusing hashCode() : Int {
go back 31
* (31 * PersonEquivalent::elegance.hashCode()
+ title.hashCode())
+ Integer.hashCode(age)

override amusing equals(different: Any?) : Boolean {
if (different == null || different !is PersonEquivalent) {
go back false
go back title == different.title && age == different.age

override amusing toString() : String {
go back String.layout(
PersonEquivalent::elegance.java.simpleName + "[name=%s, age=%s]",

println(Individual(“John”, 42).toString())
>>> Individual[name=John, age=42]

It’s conceivable in a report elegance to override the hashCode, equals, and toString strategies, successfully changing the JVM runtime generated strategies. On this case, the conduct is user-defined for those strategies.

File desugaring

Since data don’t seem to be supported on any Android software as of late, the D8/R8 desugaring engine must desugar data: it transforms the report code into code suitable with the Android VMs. File desugaring comes to remodeling the report right into a more or less an identical elegance, with out producing or compiling resources. The next Kotlin supply presentations an approximation of the generated code. For the applying code dimension to stay small, data are desugared in order that helper strategies are shared in between data.

elegance PersonDesugared(val title: String, val age: Int) {
amusing getFieldsAsObjects(): Array<Any> {
go back arrayOf(title, age)

override amusing hashCode(): Int {
go back SharedRecordHelper.hash(

override amusing equals(different: Any?): Boolean {
if (different == null || different !is PersonDesugared) {
go back false
go back getFieldsAsObjects().contentEquals(different.getFieldsAsObjects())

override amusing toString(): String {
go back SharedRecordHelper.toString(

elegance SharedRecordHelper {
significant other object {
amusing hash(recordClass: Elegance<*>, fieldValues: Array<Any>): Int {
go back 31 * recordClass.hashCode() + fieldValues.contentHashCode()

amusing toString(
fieldValues: Array<Any>,
recordClass: Elegance<*>,
fieldNames: String
: String {
val fieldNamesSplit: Checklist<String> =
if (fieldNames.isEmpty()) emptyList() else fieldNames.break up(";")
val builder: StringBuilder = StringBuilder()
for (i in fieldNamesSplit.indices) {
if (i != fieldNamesSplit.dimension - 1) {
builder.append(", ")
go back builder.toString()

File shrinking

R8 assumes that the default hashCode, equals, and toString strategies generated by means of javac successfully constitute the inner state of the report. Subsequently, if a box is minified, the strategies must mirror that; toString must print the minified title. If a box is got rid of, as an example as it has a continuing price throughout all circumstances, then the strategies must mirror that; the sector is not noted by means of the hashCode, equals, and toString strategies. When R8 makes use of the report construction within the strategies generated by means of javac, as an example when it appears to be like up fields within the report or inspects the published report construction, it is the use of mirrored image. As is the case for any use of mirrored image, you will have to write maintain regulations to tell the shrinker of the reflective use in order that it will possibly keep the construction.

In our instance, think that age is the consistent 42 around the software whilst title isn’t consistent around the software. Then toString returns other effects relying at the regulations you put:

Individual(“John”, 42).toString();

>>> Individual[name=John, age=42]

>>> a[a=John]

>>> Individual[b=John]

>>> a[name=John]

>>> a[a=John, b=42]

>>> Individual[name=John, age=42]

Reflective use circumstances

Keep toString conduct

Say you will have code that makes use of the precise printing of the report and expects it to be unchanged. For that you just will have to maintain the whole content material of the report fields with a rule corresponding to:

-keep,allowshrinking elegance Individual
-keepclassmembers,allowoptimization elegance Individual { <fields>; }

This guarantees that if the Individual report is retained within the output, any toString callproduces the very same string as it might within the authentic program. For instance:

Individual("John", 42).toString();
>>> Individual[name=John, age=42]

On the other hand, if you happen to simplest need to keep the printing for the fields which are in truth used, you’ll let the unused fields to be got rid of or contracted with allowshrinking:

-keep,allowshrinking elegance Individual
-keepclassmembers,allowshrinking,allowoptimization elegance Individual { <fields>; }

With this rule, the compiler drops the age box:

Individual("John", 42).toString();
>>> Individual[name=John]

Keep report individuals for reflective search for

If you want to reflectively get right of entry to a report member, you in most cases wish to get right of entry to its accessor manner. For that you just will have to maintain the accessor manner:

-keep,allowshrinking elegance Individual
-keepclassmembers,allowoptimization elegance Individual { java.lang.String title(); }

Now if circumstances of Individual are within the residual program you’ll safely glance up the lifestyles of the accessor reflectively:

Individual("John", 42)::elegance.java.getDeclaredMethod("title").invoke(obj);
>>> John

Understand that the former code accesses the report box the use of the accessor. For direct box get right of entry to, you want to maintain the sector itself:

-keep,allowshrinking elegance Individual
-keepclassmembers,allowoptimization elegance Individual { java.lang.String title; }

Construct techniques and the File elegance

Should you’re the use of every other construct device than AGP, the use of data might require you to evolve the construct device. The java.lang.File elegance isn’t provide till Android 14, offered within the SDK from “Android UpsideDownCake Preview” revision 4. D8/R8 introduces the com.android.gear.r8.RecordTag, an empty elegance, to suggest {that a} report subclass is a report. The RecordTag is used in order that directions referencing java.lang.File can at once be rewritten by means of desugaring to reference RecordTag and nonetheless paintings (instanceof, manner and box signatures, and so on.).

Which means each and every construct containing a connection with java.lang.File generates a man-made RecordTag elegance. In a state of affairs the place an software is divided in shards, each and every shard being compiled to a dex report, and the dex recordsdata put in combination with out merging within the Android software, this is able to result in replica RecordTag elegance.

To steer clear of the problem, any D8 intermediate construct generates the RecordTag elegance as a world artificial, in a unique output than the dex report. The dex merge step is then ready to appropriately merge world synthetics to steer clear of surprising runtime conduct. Every construct device the use of more than one compilation corresponding to sharding or intermediate outputs is needed to improve world synthetics to paintings appropriately. AGP absolutely helps data from model 8.1.


Related Articles


Please enter your comment!
Please enter your name here

Latest Articles