
Posted by Clément Béra, Senior software program engineer
Information are a brand new Java characteristic for immutable knowledge provider lessons launched in Java 16 and Android 14. To make use of information in Android Studio Flamingo, you want an Android 14 (API degree 34) SDK so the java.lang.File class is in android.jar. That is accessible from the “Android UpsideDownCake Preview” SDK revision 4. Information are primarily lessons with immutable properties and implicit hashCode, equals, and toString strategies primarily based on the underlying knowledge fields. In that respect they’re similar to Kotlin knowledge lessons. To declare a Individual document with the fields String identify and int age to be compiled to a Java document, use the next code:
|
The construct.gradle file additionally must be prolonged to make use of the right SDK and Java supply and goal. Presently the Android UpsideDownCake Preview is required, however when the Android 14 remaining SDK is launched use “compileSdk 34” and “targetSdk 34” rather than the preview model.
android { |
Information don’t essentially deliver worth in comparison with knowledge lessons in pure Kotlin packages, however they let Kotlin packages work together with Java libraries whose APIs embody information. For Java programmers this permits Java code to make use of information. Use the next code to declare the identical document in Java:
public document Individual(String identify, int age) {} |
Apart from the document flags and attributes, the document Individual is roughly equal to the next class described utilizing Kotlin supply:
class PersonEquivalent(val identify: String, val age: Int) {
|
It’s attainable in a document class to override the hashCode, equals, and toString strategies, successfully changing the JVM runtime generated strategies. On this case, the conduct is user-defined for these strategies.
File desugaring
Since information will not be supported on any Android system right now, the D8/R8 desugaring engine must desugar information: it transforms the document code into code suitable with the Android VMs. File desugaring entails remodeling the document right into a roughly equal class, with out producing or compiling sources. The next Kotlin supply reveals an approximation of the generated code. For the applying code measurement to stay small, information are desugared in order that helper strategies are shared in between information.
class PersonDesugared(val identify: String, val age: Int) {
|
File shrinking
R8 assumes that the default hashCode, equals, and toString strategies generated by javac successfully symbolize the interior state of the document. Subsequently, if a area is minified, the strategies ought to mirror that; toString ought to print the minified identify. If a area is eliminated, for instance as a result of it has a continuing worth throughout all situations, then the strategies ought to mirror that; the sector is ignored by the hashCode, equals, and toString strategies. When R8 makes use of the document construction within the strategies generated by javac, for instance when it appears up fields within the document or inspects the printed document construction, it is utilizing reflection. As is the case for any use of reflection, you could write maintain guidelines to tell the shrinker of the reflective use in order that it might probably protect the construction.
In our instance, assume that age is the fixed 42 throughout the applying whereas identify isn’t fixed throughout the applying. Then toString returns totally different outcomes relying on the foundations you set:
Individual(“John”, 42).toString();
|
Reflective use instances
Protect toString conduct
Say you’ve gotten code that makes use of the precise printing of the document and expects it to be unchanged. For that you could maintain the total content material of the document fields with a rule similar to:
-keep,allowshrinking class Individual |
This ensures that if the Individual document 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(); |
Nevertheless, for those who solely wish to protect the printing for the fields which might be really used, you’ll be able to let the unused fields to be eliminated or shrunk with allowshrinking:
-keep,allowshrinking class Individual |
With this rule, the compiler drops the age area:
Individual("John", 42).toString(); |
Protect document members for reflective lookup
If it’s essential to reflectively entry a document member, you sometimes must entry its accessor methodology. For that you could maintain the accessor methodology:
-keep,allowshrinking class Individual |
Now if situations of Individual are within the residual program you’ll be able to safely search for the existence of the accessor reflectively:
Individual("John", 42)::class.java.getDeclaredMethod("identify").invoke(obj); |
Discover that the earlier code accesses the document area utilizing the accessor. For direct area entry, it’s essential to maintain the sector itself:
-keep,allowshrinking class Individual |
Construct programs and the File class
For those who’re utilizing one other construct system than AGP, utilizing information might require you to adapt the construct system. The java.lang.File class is just not current till Android 14, launched within the SDK from “Android UpsideDownCake Preview” revision 4. D8/R8 introduces the com.android.instruments.r8.RecordTag, an empty class, to point {that a} document subclass is a document. The RecordTag is used in order that directions referencing java.lang.File can immediately be rewritten by desugaring to reference RecordTag and nonetheless work (instanceof, methodology and area signatures, and so on.).
Which means every construct containing a reference to java.lang.File generates an artificial RecordTag class. In a scenario the place an utility is cut up in shards, every shard being compiled to a dex file, and the dex recordsdata put collectively with out merging within the Android utility, this might result in duplicate RecordTag class.
To keep away from the difficulty, any D8 intermediate construct generates the RecordTag class as a world artificial, in a distinct output than the dex file. The dex merge step is then capable of appropriately merge international synthetics to keep away from surprising runtime conduct. Every construct system utilizing a number of compilation similar to sharding or intermediate outputs is required to help international synthetics to work appropriately. AGP absolutely helps information from model 8.1.