Android
Android Runtime
Fory Java supports Android 8.0+ (API level 26+) through the regular fory-core artifact. No separate
Android artifact is required for core object serialization.
Use core object serialization on Android:
Fory#serialize(Object)andFory#deserialize(byte[]).BaseFory#deserialize(ByteBuffer)for heap, direct, and read-onlyByteBufferinputs.- Stream, channel, and out-of-band buffer APIs through byte-array, heap-buffer, or
ByteBuffercopy paths. - Java collections/maps and xlang collections/maps.
java/fory-format row-format APIs are JVM-only and are not supported on Android.
Runtime Codegen
Runtime serializer code generation is disabled on Android. If withCodegen(true) is set, Fory keeps
Android serialization on the non-codegen path and logs a warning.
Android apps that need generated serializers should use build-time static generated serializers instead.
Static Generated Serializers
Use @ForyStruct static generated serializers for Android application classes. They are generated by
javac during the app build and work without runtime bytecode generation.
Install The Annotation Processor
Add fory-annotation-processor to the annotation processor path of the module that compiles your
Android model classes:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.apache.fory</groupId>
<artifactId>fory-annotation-processor</artifactId>
<version>${fory.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Then annotate Android model classes with @ForyStruct.
Static generated serializers are required on Android when a serialized class uses Fory type-use annotations, for example:
import java.util.List;
import org.apache.fory.annotation.ForyStruct;
import org.apache.fory.annotation.UInt8Type;
@ForyStruct
public class ImageBlock {
public List<@UInt8Type Integer> pixels;
}
Without the generated static descriptors, Android reflection may not expose the nested type-use
metadata needed for annotations such as @Ref, @Int8Type, @UInt8Type, @Float16Type, or
@BFloat16Type. Serialization for those classes will not have the schema information Fory needs.
See Static Generated Serializers for setup instructions.
Object Model Requirements
Android serializers use public Android APIs. For application classes, prefer:
- accessible no-argument constructors, or records with supported constructors.
- public, protected, or package-private serialized fields.
- non-private getters and setters for private serialized fields.
@ForyStructstatic generated serializers for Android model classes.
Final fields in ordinary classes are not suitable for generated read/copy methods. Use records for constructor-based immutable values.
Unsupported Features
The following JVM features are not supported on Android:
- Runtime serializer code generation and async compilation.
- Lambda and
SerializedLambdaserialization. - Native-address serialization APIs and native-address
MemoryBufferwrapping. - Raw unsafe memory copy APIs.
java/fory-formatrow-format APIs.
ByteBuffer
BaseFory#deserialize(ByteBuffer) supports heap, direct, and read-only buffers on Android by copying
the remaining bytes into a Fory-owned heap buffer. The caller buffer position and limit are not
changed.
Raw direct-buffer address wrapping is a JVM-only fast path and is not used on Android.
Collections, Maps, And Proxies
Common JDK collection and map implementations are supported on Android. In xlang mode, collection and map serialization uses the xlang protocol and does not encode Java wrapper/view internals.
java.lang.reflect.Proxy serialization is supported for normal proxy usage. Do not invoke, log, or
use a proxy as a map/set key while it is still being deserialized; the invocation handler may not be
ready yet.
Kotlin on Android
Apache Fory Kotlin supports Kotlin/JVM and Android. Android support is built on
the existing Fory Java implementation plus Kotlin serializers from
fory-kotlin. Kotlin schema serializers are generated by fory-kotlin-ksp at
build time.
Use this page for Android setup and release-build constraints. Use
Static Generated Serializers for the Kotlin
KSP serializer model itself. If your Android project also contains Java
@ForyStruct classes, use the Java annotation processor documented in
Java Static Generated Serializers.
Dependencies
Add fory-kotlin to the Android module that uses Fory. Add
fory-kotlin-ksp to the module that compiles Kotlin @ForyStruct model
classes.
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
}
dependencies {
implementation("org.apache.fory:fory-kotlin:<fory-version>")
ksp("org.apache.fory:fory-kotlin-ksp:<fory-version>")
}
For Android library modules, apply KSP in the library module that owns the annotated Kotlin classes. The generated serializers and generated consumer R8 rules must be packaged with that library artifact.
Fory Setup
Create the Fory instance with ForyKotlin.builder().withXlang(true), then register application classes
through the Kotlin register<T> extension or the normal Fory Java registration
APIs.
import org.apache.fory.kotlin.ForyKotlin
import org.apache.fory.kotlin.register
val fory = ForyKotlin.builder()
.withXlang(true)
.requireClassRegistration(true)
.build()
fory.register<User>("example.User")
Do not reference generated serializer classes from application code. Fory resolves generated serializers from the registered target class.
Xlang Schema Mode
Android Kotlin structs that participate in Fory cross-language schema serialization should use KSP generated serializers. Generated serializers avoid using runtime reflection as the source of Kotlin schema metadata and call the same Fory Java serializer infrastructure used by other generated serializers.
Kotlin KSP generated serializers are xlang/schema serializers only. They do not
replace Java native object serializers and do not preserve concrete JVM
collection implementation identity. For example, a Kotlin List<String> field
is schema list<string>; deserialization only guarantees a value assignable to
the declared field type.
Minified Release Builds
Validate Fory Android behavior with a minified release build. Debug builds do not prove that generated serializers, generated constructor entry points, or Kotlin metadata survive R8.
KSP emits generated consumer R8/ProGuard rules under META-INF/proguard/ for
the generated serializer constructors and Kotlin metadata required by Fory.
Android apps should not need broad user-written keep rules for generated Kotlin
serializers. If a custom packaging setup drops generated META-INF/proguard/
resources, fix that packaging path instead of adding broad keep rules for every
generated serializer.
The Apache Fory repository validates this path with
integration_tests/android_tests, including release-minified instrumented
tests.
Java Models In Android Apps
Kotlin KSP only processes Kotlin source. If your Android app contains Java
classes annotated with @ForyStruct, configure the Java
fory-annotation-processor for those Java sources.
Static generated Java serializers are also important on Android when Java model
classes use Fory type-use annotations on nested types, such as
List<@UInt8Type Integer>. See
Java Static Generated Serializers
for that path.
Unsupported Targets
fory-kotlin and fory-kotlin-ksp target Kotlin/JVM and Android only.
Kotlin/Native and Kotlin/JS are not supported.