{"id":13848557,"url":"https://github.com/johncarl81/parceler","last_synced_at":"2025-05-14T08:06:45.525Z","repository":{"id":9302331,"uuid":"11140459","full_name":"johncarl81/parceler","owner":"johncarl81","description":":package: Android Parcelables made easy through code generation.","archived":false,"fork":false,"pushed_at":"2022-05-20T20:48:57.000Z","size":1565,"stargazers_count":3544,"open_issues_count":33,"forks_count":273,"subscribers_count":70,"default_branch":"master","last_synced_at":"2025-04-11T02:51:54.556Z","etag":null,"topics":["android","android-parcelable","annotation-processor","boilerplate","java"],"latest_commit_sha":null,"homepage":"http://parceler.org","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"CoderMJLee/MJExtension","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johncarl81.png","metadata":{"files":{"readme":"README.asciidoc","changelog":"CHANGELOG.adoc","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-03T02:53:01.000Z","updated_at":"2025-04-07T15:15:43.000Z","dependencies_parsed_at":"2022-09-01T10:50:25.085Z","dependency_job_id":null,"html_url":"https://github.com/johncarl81/parceler","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johncarl81%2Fparceler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johncarl81%2Fparceler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johncarl81%2Fparceler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johncarl81%2Fparceler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johncarl81","download_url":"https://codeload.github.com/johncarl81/parceler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101618,"owners_count":22014909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-parcelable","annotation-processor","boilerplate","java"],"created_at":"2024-08-04T19:00:52.125Z","updated_at":"2025-05-14T08:06:40.515Z","avatar_url":"https://github.com/johncarl81.png","language":"Java","readme":"= Parceler\n\nimage:https://badges.gitter.im/johncarl81/parceler.svg[link=\"https://gitter.im/johncarl81/parceler?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge\"]\nimage:https://travis-ci.org/johncarl81/parceler.png?branch=master[\"Build Status\", link=\"https://travis-ci.org/johncarl81/parceler\"]\nimage:https://maven-badges.herokuapp.com/maven-central/org.parceler/parceler-api/badge.svg[\"Maven Central\", link=\"https://maven-badges.herokuapp.com/maven-central/org.parceler/parceler-api\"]\n\nHave a question?  http://stackoverflow.com/questions/ask?tags=parceler[Ask it on StackOverflow.]\n\nFound an issue?  https://github.com/johncarl81/parceler/issues/new[Please report it.]\n\nIn Android, http://developer.android.com/reference/android/os/Parcelable.html[Parcelables] are a great way to serialize Java Objects between Contexts.\nhttp://www.developerphil.com/parcelable-vs-serializable/[Compared] with traditional Serialization, Parcelables take on the order of 10x less time to both serialize and deserialize.\nThere is a major flaw with Parcelables, however.\nParcelables contain a ton of boilerplate code.\nTo implement a Parcelable, you must mirror the `writeToParcel()` and `createFromParcel()` methods such that they read and write to the Parcel in the same order.\nAlso, 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.\n\nParceler is a code generation library that generates the Android Parcelable boilerplate source code.\nNo longer do you have to implement the Parcelable interface, the `writeToParcel()` or `createFromParcel()` or the `public static final CREATOR`.\nYou simply annotate a POJO with `@Parcel` and Parceler does the rest.\nBecause Parceler uses the Java JSR-269 Annotation Processor, there is no need to run a tool manually to generate the Parcelable code.\nJust annotate your Java Bean, compile and you are finished.\nBy default, Parceler will serialize the fields of your instance directly:\n\n[source,java]\n----\n@Parcel\npublic class Example {\n    String name;\n    int age;\n\n    public Example() {}\n\n    public Example(int age, String name) {\n        this.age = age;\n        this.name = name;\n    }\n\n    public String getName() { return name; }\n\n    public int getAge() { return age; }\n}\n----\n\nBe careful not to use private fields when using the default field serialization strategy as it will incur a performance penalty due to reflection.\n\nTo use the generated code, you may reference the generated class directly, or via the `Parcels` utility class:\n\n[source,java]\n----\nParcelable wrapped = Parcels.wrap(new Example(\"Andy\", 42));\n----\n\nTo dereference the `@Parcel`, just call the `Parcels.unwrap()` method:\n\n[source,java]\n----\nExample example = Parcels.unwrap(wrapped);\nexample.getName(); // Andy\nexample.getAge(); // 42\n----\n\nOf course, the wrapped `Parcelable` can be added to an Android Bundle to transfer from Activity to Activity:\n\n[source,java]\n----\nBundle bundle = new Bundle();\nbundle.putParcelable(\"example\", Parcels.wrap(example));\n----\n\nAnd dereferenced in the `onCreate()` method:\n\n[source,java]\n----\nExample example = Parcels.unwrap(getIntent().getParcelableExtra(\"example\"));\n----\n\nThis wrapping and unwrapping technique plays well with the Intent Factory pattern.\nIn addition, Parceler is supported by the following libraries:\n\n * http://androidtransfuse.org/documentation.html#parcel[Transfuse] - Allows `@Parcel` annotated beans to be used with the `@Extra` injection.\n * https://github.com/sockeqwe/fragmentargs#argsbundler[FragmentArgs] - Uses the `ParcelerArgsBundler` adapter to wrap and unwrap `@Parcel` annotated beans with fragment parameters.\n * https://github.com/f2prateek/dart[Dart] - Autodetects `@Parcel` annotated beans and automatically unwraps them when using `@InjectExtra`.\n * http://androidannotations.org/[AndroidAnnotations] - Autodetects `@Parcel` annotated beans and https://github.com/excilys/androidannotations/wiki/ParcelerIntegration[automatically wraps/unwraps] them when using `@Extra`, `@FragmentArg`, `@InstanceState` and other `Bundle` related annotations.\n * https://github.com/MarcinMoskala/ActivityStarter/wiki/Parceler-Arg-Converter-usage[ActivityStarter] - Supports natively Parceler objects as arguments to Activities, Fragments, Services, etc.\n * https://josesamuel.com/remoter/[Remoter] - Supports natively Parceler objects as arguments in @Remoter interfaces. \n\n=== Parcel attribute types\nOnly a select number of types may be used as attributes of a `@Parcel` class.\nThe following list includes the mapped types:\n\n * `byte`\n * `double`\n * `float`\n * `int`\n * `long`\n * `char`\n * `boolean`\n * `String`\n * `IBinder`\n * `Bundle`\n * `SparseArray` of any of the mapped types*\n * `SparseBooleanArray`\n * `ObservableField`\n * `List`, `ArrayList` and `LinkedList` of any of the mapped types*\n * `Map`, `HashMap`, `LinkedHashMap`, `SortedMap`, and `TreeMap` of any of the mapped types*\n * `Set`, `HashSet`, `SortedSet`, `TreeSet`, `LinkedHashSet` of any of the mapped types*\n * `Parcelable`\n * `Serializable`\n * Array of any of the mapped types\n * Any other class annotated with `@Parcel`\n\n*Parcel will error if the generic parameter is not mapped.\n\nParceler also supports any of the above types directly.\nThis is especially useful when dealing with collections of classes annotated with `@Parcel`:\n\n[source,java]\n----\nParcelable listParcelable = Parcels.wrap(new ArrayList\u003cExample\u003e());\nParcelable mapParcelable = Parcels.wrap(new HashMap\u003cString, Example\u003e());\n----\n\n==== Polymorphism\nNote that Parceler does not unwrap inheritance hierarchies, so any polymorphic fields will be unwrapped as instances of the base class.\nThis is because Parceler opts for performance rather than checking `.getClass()` for every piece of data.\n\n[source,java]\n----\n@Parcel\npublic class Example {\n    public Parent p;\n    @ParcelConstructor Example(Parent p) { this.p = p; }\n}\n\n@Parcel public class Parent {}\n@Parcel public class Child extends Parent {}\n----\n\n[source,java]\n----\nExample example = new Example(new Child());\nSystem.out.println(\"%b\", example.p instanceof Child); // true\nexample = Parcels.unwrap(Parcels.wrap(example));\nSystem.out.println(\"%b\", example.p instanceof Child); // false\n----\n\nRefer to the \u003c\u003ccustom-serialization,Custom Serialization\u003e\u003e section for an example of working with polymorphic fields.\n\n=== Serialization techniques\n\nParceler offers several choices for how to serialize and deserialize an object in addition to the field-based serialization seen above.\n\n==== Getter/setter serialization\nParceler may be configured to serialize using getter and setter methods and a non-empty constructor.\nIn addition, fields, methods and constructor parameters may be associated using the `@ParcelProperty` annotation.\nThis supports a number of bean strategies including immutability and traditional getter/setter beans.\n\nTo configure default method serialization, simply configure the `@Parcel` annotation with `Serialization.BEAN`:\n\n[source,java]\n----\n@Parcel(Serialization.BEAN)\npublic class Example {\n    private String name;\n    private int age;\n    private boolean enabled;\n\n    public String getName() { return name; }\n    public void setName(String name) { this.name = name; }\n\n    public int getAge() { return age; }\n    public void setAge(int age) { this.age = age; }\n    \n    public boolean isEnabled() { return enabled; }\n    public void setEnabled(boolean enabled) { this.enabled = enabled; }\n}\n----\n\nTo use a constructor with serialization, annotate the desired constructor with the `@ParcelConstructor` annotation:\n\n[source,java]\n----\n@Parcel(Serialization.BEAN)\npublic class Example {\n    private final String name;\n    private final int age;\n    private boolean enabled;\n\n    @ParcelConstructor\n    public Example(int age, String name, boolean enabled) {\n        this.age = age;\n        this.name = name;\n        this.enabled = enabled;\n    }\n\n    public String getName() { return name; }\n\n    public int getAge() { return age; }\n    \n    public boolean isEnabled() { return enabled; }\n}\n----\n\nIf an empty constructor is present, Parceler will use that constructor unless another constructor is annotated.\n\n==== Mixing getters/setters and fields\nYou may also mix and match serialization techniques using the `@ParcelProperty` annotation.\nIn 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.\nThe parameters `firstName` and `lastName` are coordinated by the parameter names `\"first\"` and `\"last\"` respectfully.\n\n[source,java]\n----\n@Parcel\npublic class Example {\n    @ParcelProperty(\"first\")\n    String firstName;\n    String lastName;\n\n    @ParcelConstructor\n    public Example(@ParcelProperty(\"first\") String firstName, @ParcelProperty(\"last\") String lastName){\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    public String getFirstName() { return firstName; }\n\n    @ParcelProperty(\"last\")\n    public String getLastName() { return lastName; }\n}\n----\n\nFor attributes that should not be serialized with Parceler, the attribute field, getter or setter may be annotated by `@Transient`.\n\nParceler supports many different styles centering around the POJO.\nThis allows `@Parcel` annotated classes to be used with other POJO based libraries, including the following:\n\n * https://code.google.com/p/google-gson/[GSON]\n * https://realm.io/docs/java/latest/#parceler[Realm]\n * https://bitbucket.org/littlerobots/cupboard[Cupboard]\n * http://simple.sourceforge.net/[Simple XML]\n * https://github.com/Raizlabs/DBFlow[DBFlow]\n\n==== Static Factory support\nAs an alternative to using a constructor directly, Parceler supports using an annotated Static Factory to build an instance of the given class.\nThis style supports Google's https://github.com/google/auto/tree/master/value[AutoValue] annotation processor / code generation library for generating immutable beans.\nParceler interfaces with AutoValue via the `@ParcelFactory` annotation, which maps a static factory method into the annotated `@Parcel` serialization:\n\n[source,java]\n----\n@AutoValue\n@Parcel\npublic abstract class AutoValueParcel {\n\n    @ParcelProperty(\"value\") public abstract String value();\n\n    @ParcelFactory\n    public static AutoValueParcel create(String value) {\n        return new AutoValue_AutoValueParcel(value);\n    }\n}\n----\n\nAutoValue generates a different class than the annotated `@Parcel`, therefore, you need to specify which class Parceler should build in the `Parcels` utility class:\n\n[source,java]\n----\nParcelable wrappedAutoValue = Parcels.wrap(AutoValueParcel.class, AutoValueParcel.create(\"example\"));\n----\nAnd to deserialize:\n[source,java]\n----\nAutoValueParcel autoValueParcel = Parcels.unwrap(wrappedAutoValue);\n----\n\n==== Custom serialization\n`@Parcel` includes an optional parameter to include a manual serializer `ParcelConverter` for the case where special serialization is necessary.\nThis provides a still cleaner option for using Parcelable classes than implementing them by hand.\n\nThe following code demonstrates using a `ParcelConverter` to unwrap the inheritance hierarchy during deserialization.\n\n[source,java]\n----\n@Parcel\npublic class Item {\n    @ParcelPropertyConverter(ItemListParcelConverter.class)\n    public List\u003cItem\u003e itemList;\n}\n@Parcel public class SubItem1 extends Item {}\n@Parcel public class SubItem2 extends Item {}\n\npublic class ItemListParcelConverter implements ParcelConverter\u003cList\u003cItem\u003e\u003e {\n    @Override\n    public void toParcel(List\u003cItem\u003e input, Parcel parcel) {\n        if (input == null) {\n            parcel.writeInt(-1);\n        }\n        else {\n            parcel.writeInt(input.size());\n            for (Item item : input) {\n                parcel.writeParcelable(Parcels.wrap(item), 0);\n            }\n        }\n    }\n\n    @Override\n    public List\u003cItem\u003e fromParcel(Parcel parcel) {\n        int size = parcel.readInt();\n        if (size \u003c 0) return null;\n        List\u003cItem\u003e items = new ArrayList\u003cItem\u003e();\n        for (int i = 0; i \u003c size; ++i) {\n            items.add((Item) Parcels.unwrap(parcel.readParcelable(Item.class.getClassLoader())));\n        }\n        return items;\n    }\n}\n----\n\nParceler is also packaged with a series of base classes to make Collection conversion easier located under the `org.parceler.converter` package of the api.\nThese base classes take care of a variety of difficult or verbose jobs dealing with Collections including null checks and collectin iteration.\nFor instance, the above `ParcelConverter` could be written using the `ArrayListParcelConverter':\n\n[source,java]\n----\npublic class ItemListParcelConverter extends ArrayListParcelConverter\u003cItem\u003e {\n    @Override\n    public void itemToParcel(Item item, Parcel parcel) {\n        parcel.writeParcelable(Parcels.wrap(item), 0);\n    }\n\n    @Override\n    public Item itemFromParcel(Parcel parcel) {\n        return Parcels.unwrap(parcel.readParcelable(Item.class.getClassLoader()));\n    }\n}\n----\n\n=== Classes without Java source\nFor classes whose corresponding Java source is not available, one may include the class as a Parcel by using the `@ParcelClass` annotation.\nThis annotation may be declared anywhere in the compiled source that is convenient.\nFor instance, one could include the `@ParcelClass` along with the Android Application:\n\n[source,java]\n----\n@ParcelClass(LibraryParcel.class)\npublic class AndroidApplication extends Application{\n    //...\n}\n----\n\nMultiple `@ParcelClass` annotations may be declared using the `@ParcelClasses` annotation.\n\nIn addition, classes referenced by `@ParcelClass` may be configured using the `@Parcel` annotation.\nThis allows the serialization configuration through any parameter available on the `@Parcel` annotation including the serialization technique or classes to analyze.\n\nOne useful technique is the ability to define global custom converters for a type:\n[source,java]\n----\n@ParcelClass(\n    value = LibraryParcel.class,\n    annotation = @Parcel(converter = LibraryParcelConverter.class))\nclass SomeClass{}\n----\nThis allows for fine grained control over a class that isn't available for direct modification.\n\n=== Advanced configuration\n\n==== Skipping analysis\nIt is a common practice for some libraries to require a bean to extend a base class.\nAlthough 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:\n\n[source, java]\n----\n@Parcel(analyze = {One.class, Three.class})\nclass One extends Two {}\nclass Two extends Three {}\nclass Three extends BaseClass {}\n----\n\nIn this example, only fields of the `One` and `Three` classes will be serialized, avoiding both the `BaseClass` and `Two` class parameters.\n\n==== Specific wrapping\n\nThe Parcels utility class looks up the given class for wrapping by class.\nFor performance reasons this ignores inheritance, both super and base classes.\nThere are two solutions to this problem.\nFirst, one may specify additional types to associate to the given type via the `implementations` parameter:\n\n[source, java]\n----\nclass ExampleProxy extends Example {}\n@Parcel(implementations = {ExampleProxy.class})\nclass Example {}\n\nExampleProxy proxy = new ExampleProxy();\nParcels.wrap(proxy);  // ExampleProxy will be serialized as a Example\n----\n\nSecond, one may also specify the class type when using the `Parcels.wrap()` method:\n\n[source, java]\n----\nExampleProxy proxy = new ExampleProxy();\nParcels.wrap(Example.class, proxy);\n----\n\n==== Configuring Proguard\n\nTo 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:\ner\n----\n# Parceler library\n-keep interface org.parceler.Parcel\n-keep @org.parceler.Parcel class * { *; }\n-keep class **$$Parcelable { *; }\n----\n\n== Getting Parceler\n\nYou may download Parceler as a Maven dependency:\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.parceler\u003c/groupId\u003e\n    \u003cartifactId\u003eparceler\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.12\u003c/version\u003e\n    \u003cscope\u003eprovided\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.parceler\u003c/groupId\u003e\n    \u003cartifactId\u003eparceler-api\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.12\u003c/version\u003e\n\u003c/dependency\u003e\n----\n\nor Gradle:\n[source,groovy]\n----\nimplementation 'org.parceler:parceler-api:1.1.12'\nannotationProcessor 'org.parceler:parceler:1.1.12'\n----\n\nOr from http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.parceler%22[Maven Central].\n\n== License\n----\nCopyright 2011-2015 John Ericksen\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n----\n","funding_links":[],"categories":["Java","java","Libs","Parcelables","Annotation"],"sub_categories":["\u003cA NAME=\"Code_Generation\"\u003e\u003c/A\u003eCode Generation"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohncarl81%2Fparceler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohncarl81%2Fparceler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohncarl81%2Fparceler/lists"}