Auto-Parcel


Source link: https://github.com/aitorvs/auto-parcel

Auto-Parcel

A fast annotation processor to make your objects Parcelable without writing any of the boilerplate.

The project is inspired in auto-value-parcel extension and some of the code and utils are borrowed from it.

Background

Parcelable classes are great to put your objects into a Bundle and/or send them across an Intent. But there is a non-negligible boilerplate one has to write to make a class parcelable and, let's be clear, nobody should ever need to write this code. It is uninteresting code and highly prone to error.

There are a number of libraries out there to make your life simpler when using parcelables. Some create wrappers around your object to parcel/unparcel, some others generate code. This is yet-another-parcelable-library that uses Android Studio annotation processors to generate your parcelable classes at compile time.

Installation

Repository

Add the following repo to your app/build.gradle

repositories {

  maven {
 url "https://jitpack.io" 
}
 
}

Dependencies

Add the following to gradle dependencies:

dependencies {

 //... other dependencies here

 provided 'com.github.aitorvs.auto-parcel:library:0.2.0'
  apt 'com.github.aitorvs.auto-parcel:compiler:0.2.0' 
}

The annotation processor requires android-apt plugin.

Usage

The use of the library is very simple. Just create an abstract Parcelable-to-be class, annotate it with @AutoParcel and it will do the rest.

import com.aitorvs.autoparcel.AutoParcel;  @AutoParcel public abstract class Person {

  @Nullable
  public String name;
  public int age;

public static Person create(@NonNull String name, int age) {

return new AutoParcel_Person(name, age);

  
}
 
}

AutoParcel will generate a parcelable class that extends from the abstract class you created. The generated class name follows the convention AutoParcel_<YouClassName>.

You will need to add a convenience builder method (e.g. creator) that calls the generated class constructor and that is all there is to it.

You are ready now to e.g. send an instance of Person across an intent

intent.putExtra(EXTRA_PERSON, (Parcelable) person);
 

To avoid the need to cast Person to (Parcelable) just add implements Parcelable to your abstract class definition. AutoParcel will detect it and do the rest anyway.

@AutoParcel public abstract class Person implements Parcelable {
...
}
 

It is important to note that AutoParcel errors out when private fields are found, because they are not accessible from the generated class. Use either protected or public instead.

Parcel Adapters

AutoParcel supports all types supported by Parcel with the exception of Map -- why? read here.

At times you will also need to parcel more complex types. For that, use ParcelAdapters. Let's see an example for a Date parcel adapter.

import android.os.Parcel; import com.aitorvs.autoparcel.ParcelTypeAdapter; import java.util.Date;  class DateTypeAdapter implements ParcelTypeAdapter<Date> {

  @Override
  public Date fromParcel(Parcel in) {

return new Date(in.readLong());

  
}

@Override
  public void toParcel(Date value, Parcel dest) {

dest.writeLong(value.getTime());

  
}
 
}

Now you can use your adapter into your classes.

import com.aitorvs.autoparcel.AutoParcel;  @AutoParcel public abstract class Person {

  @Nullable
  public String name;
  @ParcelAdapter(DateTypeAdapter.class)
  public Date birthday;
  public int age;

public static Person create(@NonNull String name, @NonNull Date birthday, int age) {

return new AutoParcel_Person(name, birthday, age);

  
}
 
}

Parcel adapters are optional and the require the ParcelTypeAdapter runtime component. To use them just add to your gradle the following dependency.

compile 'com.github.aitorvs.auto-parcel:adapter:0.2.0' 

Version-able Parcels

Use case: your app issues a notification and within the pending intent, it parcels some model object. Overtime, your model changes, adding some new fields, so you update the app. A user of your app has a notification yet to be read but, before that happens, the app gets updated. Now when your user opens the notification, the new version of the app will try to render from the Parcel a different version of the of the object model...not good!

Using @ParcelVersion field annotation in combination with the version optional parameter in @AutoParcel class annotation you can render data from Parcels with different versions.

Let's say we have an object model Person.

@AutoParcel public abstract class Person implements Parcelable {

  @NonNull
  public String name;

@ParcelAdapter(DateTypeAdapter.class)
  public Date birthday;

public int age;

public static Person create(@NonNull String name, @NonNull Date birthday, int age) {

return new AutoParcel_Person(name, birthday, age);

  
}
 
}

At some point in our development, we decided that Person deserves also a field lastName, so we update the model, add the field and release a new version of the app. But we want our app to also render correctly previous object models (without the lastName)

Easy, just update the model like this:

@AutoParcel(version = 1) public abstract class Person implements Parcelable {

  @NonNull
  public String name;

@ParcelVersion(from = 1)
  @Nullable
  public String lastName;

@ParcelAdapter(DateTypeAdapter.class)
  public Date birthday;

public int age;

public static Person create(@NonNull String name, String lastName, @NonNull Date birthday, int age) {

return new AutoParcel_Person(name, lastName, birthday, age);

  
}
 
}

What we've done:

  • Increase the version of our Parcelable object to 1 -- default version is 0
  • Annotate the new field with @ParcelVersion(from = 1) that indicates the field was added in version 1

The library will take care of the rest.

Pitfalls

  • Bootstrap is somehow annoying because when typing your first AutoParcel_Foo it will turn red in the IDE until the first build is performed.
  • Order of the constructor AutoParcel_Foo parameters is important and according to their appearance in the source file.

License

Copyright 2016 Aitor Viana Sánchez.  Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License. You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 

Resources

This library runs background service that is listening for shake movements in device.

Android library for material scrolling techniques.

Features:

  • Easily implement material scrolling techniques with RecyclerView.
  • Customize the behavior while scrolling.
  • Support RecyclerView in ViewPager.

This tool can retrieve dex, jar, smali, xml files, res, etc.

BatchPackApk is a tool for batch package Android apk with channel string.

A pretty label view.

Android Library to handle SharedPreferences boilerplate code and other tools.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes