This document provides a comprehensive overview of Parceler, a code generation library for Android that simplifies the creation of Parcelable objects. It details Parceler's features, including supported data types, serialization techniques, handling of polymorphism, and advanced configurations, along with integration with other popular Android libraries. The latter part introduces Mitsuba 3, a research-oriented rendering system, outlining its features, installation, and usage.
Parceler
Have a question? Ask it on StackOverflow.
Found an issue? Please report it.
In Android, Parcelables are a great way to serialize Java Objects between Contexts.
Compared with traditional Serialization, Parcelables take on the order of 10x less time to both serialize and deserialize.
There is a major flaw with Parcelables, however.
Parcelables contain a ton of boilerplate code.
To implement a Parcelable, you must mirror the writeToParcel() and createFromParcel() methods such that they read and write to the Parcel in the same order.
Also, a Parcelable must define a public static final Parcelable.Creator CREATOR in order for the Android infrastructure to be able to leverage the serialization code.
Parceler is a code generation library that generates the Android Parcelable boilerplate source code.
No longer do you have to implement the Parcelable interface, the writeToParcel() or createFromParcel() or the public static final CREATOR.
You simply annotate a POJO with @Parcel and Parceler does the rest.
Because Parceler uses the Java JSR-269 Annotation Processor, there is no need to run a tool manually to generate the Parcelable code.
Just annotate your Java Bean, compile and you are finished.
By default, Parceler will serialize the fields of your instance directly:
Be careful not to use private fields when using the default field serialization strategy as it will incur a performance penalty due to reflection.
To use the generated code, you may reference the generated class directly, or via the Parcels utility class:
To dereference the @Parcel, just call the Parcels.unwrap() method:
Of course, the wrapped Parcelable can be added to an Android Bundle to transfer from Activity to Activity:
And dereferenced in the onCreate() method:
This wrapping and unwrapping technique plays well with the Intent Factory pattern.
In addition, Parceler is supported by the following libraries:
Transfuse - Allows @Parcel annotated beans to be used with the @Extra injection.
FragmentArgs - Uses the ParcelerArgsBundler adapter to wrap and unwrap @Parcel annotated beans with fragment parameters.
Dart - Autodetects @Parcel annotated beans and automatically unwraps them when using @InjectExtra.
AndroidAnnotations - Autodetects @Parcel annotated beans and automatically wraps/unwraps them when using @Extra, @FragmentArg, @InstanceState and other Bundle related annotations.
ActivityStarter - Supports natively Parceler objects as arguments to Activities, Fragments, Services, etc.
Remoter - Supports natively Parceler objects as arguments in @Remoter interfaces.
Parcel attribute types
Only a select number of types may be used as attributes of a @Parcel class.
The following list includes the mapped types:
byte
double
float
int
long
char
boolean
String
IBinder
Bundle
SparseArray of any of the mapped types*
SparseBooleanArray
ObservableField
List, ArrayList and LinkedList of any of the mapped types*
Map, HashMap, LinkedHashMap, SortedMap, and TreeMap of any of the mapped types*
Set, HashSet, SortedSet, TreeSet, LinkedHashSet of any of the mapped types*
Parcelable
Serializable
Array of any of the mapped types
Any other class annotated with @Parcel
*Parcel will error if the generic parameter is not mapped.
Parceler also supports any of the above types directly.
This is especially useful when dealing with collections of classes annotated with @Parcel:
Polymorphism
Note that Parceler does not unwrap inheritance hierarchies, so any polymorphic fields will be unwrapped as instances of the base class.
This is because Parceler opts for performance rather than checking .getClass() for every piece of data.
Refer to the Custom Serialization section for an example of working with polymorphic fields.
Serialization techniques
Parceler offers several choices for how to serialize and deserialize an object in addition to the field-based serialization seen above.
Getter/setter serialization
Parceler may be configured to serialize using getter and setter methods and a non-empty constructor.
In addition, fields, methods and constructor parameters may be associated using the @ParcelProperty annotation.
This supports a number of bean strategies including immutability and traditional getter/setter beans.
To configure default method serialization, simply configure the @Parcel annotation with Serialization.BEAN:
To use a constructor with serialization, annotate the desired constructor with the @ParcelConstructor annotation:
If an empty constructor is present, Parceler will use that constructor unless another constructor is annotated.
Mixing getters/setters and fields
You may also mix and match serialization techniques using the @ParcelProperty annotation.
In the following example, firstName and lastName are written to the bean using the constructor while firstName is read from the bean using the field and lastName is read using the getLastName() method.
The parameters firstName and lastName are coordinated by the parameter names "first" and "last" respectfully.
For attributes that should not be serialized with Parceler, the attribute field, getter or setter may be annotated by @Transient.
Parceler supports many different styles centering around the POJO.
This allows @Parcel annotated classes to be used with other POJO based libraries, including the following:
GSON
Realm
Cupboard
Simple XML
DBFlow
Static Factory support
As an alternative to using a constructor directly, Parceler supports using an annotated Static Factory to build an instance of the given class.
This style supports Google’s AutoValue annotation processor / code generation library for generating immutable beans.
Parceler interfaces with AutoValue via the @ParcelFactory annotation, which maps a static factory method into the annotated @Parcel serialization:
AutoValue generates a different class than the annotated @Parcel, therefore, you need to specify which class Parceler should build in the Parcels utility class:
And to deserialize:
Custom serialization
@Parcel includes an optional parameter to include a manual serializer ParcelConverter for the case where special serialization is necessary.
This provides a still cleaner option for using Parcelable classes than implementing them by hand.
The following code demonstrates using a ParcelConverter to unwrap the inheritance hierarchy during deserialization.
Parceler is also packaged with a series of base classes to make Collection conversion easier located under the org.parceler.converter package of the api.
These base classes take care of a variety of difficult or verbose jobs dealing with Collections including null checks and collectin iteration.
For instance, the above ParcelConverter could be written using the `ArrayListParcelConverter':
Classes without Java source
For classes whose corresponding Java source is not available, one may include the class as a Parcel by using the @ParcelClass annotation.
This annotation may be declared anywhere in the compiled source that is convenient.
For instance, one could include the @ParcelClass along with the Android Application:
Multiple @ParcelClass annotations may be declared using the @ParcelClasses annotation.
In addition, classes referenced by @ParcelClass may be configured using the @Parcel annotation.
This allows the serialization configuration through any parameter available on the @Parcel annotation including the serialization technique or classes to analyze.
One useful technique is the ability to define global custom converters for a type:
This allows for fine grained control over a class that isn’t available for direct modification.
Advanced configuration
Skipping analysis
It is a common practice for some libraries to require a bean to extend a base class.
Although it is not the most optimal case, Parceler supports this practice by allowing the configuration of what classes in the inheritance hierarchy to analyze via the analyze parameter:
In this example, only fields of the One and Three classes will be serialized, avoiding both the BaseClass and Two class parameters.
Specific wrapping
The Parcels utility class looks up the given class for wrapping by class.
For performance reasons this ignores inheritance, both super and base classes.
There are two solutions to this problem.
First, one may specify additional types to associate to the given type via the implementations parameter:
Second, one may also specify the class type when using the Parcels.wrap() method:
Configuring Proguard
To configure Proguard, add the following lines to your proguard configuration file. These will keep files related to the Parcels utilty class and the Parcelable CREATOR instance:
er
Getting Parceler
You may download Parceler as a Maven dependency:
or Gradle:
Or from Maven Central.
License
example:
Mitsuba Renderer 3
Documentation
|
Tutorial videos
|
Linux
|
MacOS
|
Windows
|
PyPI
|
---|---|---|---|---|---|
️
Warning
️
There currently is a large amount of undocumented and unstable work going on in
the master
branch. We'd highly recommend you use our
latest release
until further notice.
If you already want to try out the upcoming changes, please have a look at
this porting guide.
It should cover most of the new features and breaking changes that are coming.
Introduction
Mitsuba 3 is a research-oriented rendering system for forward and inverse light
transport simulation developed at EPFL in Switzerland.
It consists of a core library and a set of plugins that implement functionality
ranging from materials and light sources to complete rendering algorithms.
Mitsuba 3 is retargetable: this means that the underlying implementations and
data structures can transform to accomplish various different tasks. For
example, the same code can simulate both scalar (classic one-ray-at-a-time) RGB transport
or differential spectral transport on the GPU. This all builds on
Dr.Jit, a specialized just-in-time(JIT) compiler developed specifically for this project.
Main Features
Cross-platform: Mitsuba 3 has been tested on Linux (x86_64
), macOS
(aarch64
, x8664
), and Windows (x8664
).
High performance: The underlying Dr.Jit compiler fuses rendering code
into kernels that achieve state-of-the-art performance using
an LLVM backend targeting the CPU and a CUDA/OptiX backend
targeting NVIDIA GPUs with ray tracing hardware acceleration.
Python first: Mitsuba 3 is deeply integrated with Python. Materials,
textures, and even full rendering algorithms can be developed in Python,
which the system JIT-compiles (and optionally differentiates) on the fly.
This enables the experimentation needed for research in computer graphics and
other disciplines.
Differentiation: Mitsuba 3 is a differentiable renderer, meaning that it
can compute derivatives of the entire simulation with respect to input
parameters such as camera pose, geometry, BSDFs, textures, and volumes. It
implements recent differentiable rendering algorithms developed at EPFL.
Spectral & Polarization: Mitsuba 3 can be used as a monochromatic
renderer, RGB-based renderer, or spectral renderer. Each variant can
optionally account for the effects of polarization if desired.
Tutorial videos, documentation
We've recorded several YouTube videos that provide a gentle introduction
Mitsuba 3 and Dr.Jit. Beyond this you can find complete Juypter notebooks
covering a variety of applications, how-to guides, and reference documentation
on readthedocs.
Installation
We provide pre-compiled binary wheels via PyPI. Installing Mitsuba this way is as simple as running
pip install mitsuba
on the command line. The Python package includes thirteen variants by default:
scalar_rgb
scalar_spectral
scalarspectralpolarized
llvmadrgb
llvmadmono
llvmadmono_polarized
llvmadspectral
llvmadspectral_polarized
cudaadrgb
cudaadmono
cudaadmono_polarized
cudaadspectral
cudaadspectral_polarized
The first two perform classic one-ray-at-a-time simulation using either a RGB
or spectral color representation, while the latter two can be used for inverse
rendering on the CPU or GPU. To access additional variants, you will need to
compile a custom version of Dr.Jit using CMake. Please see the
documentation
for details on this.
Requirements
Python >= 3.8
(optional) For computation on the GPU: Nvidia driver >= 495.89
(optional) For vectorized / parallel computation on the CPU: LLVM >= 11.1
Usage
Here is a simple "Hello World" example that shows how simple it is to render a
scene using Mitsuba 3 from Python:
# Import the library using the alias "mi"import mitsuba as mi# Set the variant of the renderermi.setvariant('scalarrgb')# Load a scenescene = mi.loaddict(mi.cornellbox())# Render the sceneimg = mi.render(scene)# Write the rendered image to an EXR filemi.Bitmap(img).write('cbox.exr')
Tutorials and example notebooks covering a variety of applications can be found
in the documentation.
About
This project was created by Wenzel Jakob.
Significant features and/or improvements to the code were contributed by
Sébastien Speierer,
Nicolas Roussel,
Merlin Nimier-David,
Delio Vicini,
Tizian Zeltner,
Baptiste Nicolet,
Miguel Crespo,
Vincent Leroy, and
Ziyi Zhang.
When using Mitsuba 3 in academic projects, please cite:
@software{Mitsuba3,title = {Mitsuba 3 renderer},author = {Wenzel Jakob and Sébastien Speierer and Nicolas Roussel and Merlin Nimier-David and Delio Vicini and Tizian Zeltner and Baptiste Nicolet and Miguel Crespo and Vincent Leroy and Ziyi Zhang},note = {https://mitsuba-renderer.org},version = {3.1.1},year = 2022}