Coder Social home page Coder Social logo

grandstaish / paperparcel Goto Github PK

View Code? Open in Web Editor NEW
497.0 497.0 29.0 16.27 MB

Auto-generate Parcelable implementations for Java and Kotlin

Home Page: https://grandstaish.github.io/paperparcel/

License: Apache License 2.0

Java 99.68% Kotlin 0.32%
android android-parcelable annotation-processor autovalue-extension

paperparcel's People

Contributors

ansman avatar ayanyev avatar bejibx avatar edenman avatar grandstaish avatar johnjohndoe avatar josh-burton avatar koral-- avatar paulblessing avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paperparcel's Issues

PaperParcel breaks Butterknife

I have an Android Java project with some Kotlin files.
Adding PaperParcel breaks Butterknife. With PaperParcel, after ButterKnife.bind(this); the bound views are null.

I reproduced the issue in a fork here, in the java-exemple module.

In java-exemple, remove

    compile 'com.github.grandstaish.paperparcel:paperparcel:1.0.0-beta3'
    kapt 'com.github.grandstaish.paperparcel:compiler:1.0.0-beta3'

from the build.gradle to check that Butterknife is working when PaperParcel is not used.

Proguard breaks beta6

I added -keep class nz.bradcampbell.paperparcel.** { *; } to my proguard-rules, which resolves the issue on my end, but if it can't be resolved internally, recommend adding a note in the README.

Excerpt:

E/AndroidRuntime: FATAL EXCEPTION: main
...
java.lang.ExceptionInInitializerError
 at nz.bradcampbell.paperparcel.h.a(Unknown Source)
...
Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: No field FROM_ORIGINAL in class Lnz/bradcampbell/paperparcel/a; (declaration of 'nz.bradcampbell.paperparcel.a' appears in /data/app/**package name**/base.apk)
...       

Travis build is broken, can't find android-23

This was passing before, and with no changes to the travis configuration it somehow decided to fail. If anyone who knows Travis can help with this, I would greatly appreciate it

Remove all calls to readValue/writeValue

The runtime overhead of instanceof checks actually seems quite high. Also it removes the ability for performance improvements, e.g. not storing an int for null-safety if we know it's not nullable.

These methods are currently used for all boxed primitives. Those types can all be parcelled in the same way as the primitives are.

Improve sample apps

The sample app is too simplistic. A better sample would show a parcelling/unparcelling more complex objects

Add support for having no null checks for container items

Although kotlin's compiler knows that List<Value> can't contain contain null values but List<Value?> can, the compiled class file loses this information. For that reason, PaperParcel will always do a null-check on every item within a container (e.g. list, map, array, etc). It would be nice to be able to opt-in to say "none of these items can ever be null" and hence remove the extraneous checking.

PaperParcel trying to generate Parcel class for LatLng

Hi,
I'm seeing an issue in one of my data class I want to parcel, because it contains a LatLng property.
While LatLng does not implement directly Parcelable interface, it implements SafeParcelable which itself implements Parcelable.

I tried to provide a global type adapter for LatLng but it didn't seem to work:

@GlobalTypeAdapter
class LatLngParcelTypeAdapter : TypeAdapter<LatLng> {

    override fun readFromParcel(parcel: Parcel): LatLng {
        return parcel.readParcelable(LatLng::class.java.classLoader)
    }

    override fun writeToParcel(latLng: LatLng, parcel: Parcel) {
        parcel.writeParcelable(latLng, 0)
    }
}

Even though it would work, it would still be nice that the library recognises the type and uses it as a Parcelable ready entity.

Thanks for great library,
Lukasz

Question: would it be possible to use extensions

Having annotation is quite small code change. But would it be possible to have extension which accepts an object and saves/load it from parcel.

At least current API could be improved with extension to avoid using util classes

Remove Parcel constructor from the generated wrappers

Attempt to be a good Android citizen and keep the generated classes as light on the method count as possible. This will remove one method per generated class.

This constructor is not needed as the data class can be built directly inside of the CREATOR iteself.

Kotlin delegated property breaks compilation

Say we have a simple Kotlin data class:

@PaperParcel
data class File(val filePath: String) {
}

We want to determine the file name using the path. One approach is to add a function:

fun name(): String {
  val name: String
  // Calculate file name from path
  return name
}

This makes us calculate the name often. Instead, we choose to use a delegated property:

val name: String by lazy {
    // Calculate file name from path. Done only once
}

This breaks the compiler as the name is a delegated property, not a member property. Using @GetterMethodName also doesn't work for this reason.

Allow @PaperParcel to be put on a data class with type parameters

I'm not sure how this should work yet, but some things to consider are:

  • It must work with type adapters, e.g. if T is List<Date>, then any scoped TypeAdapter<Date> must still be used to parcel the dates.
  • The class of T can only be determined at runtime so it won't be possible to make this fail at compile-time if it is used with some non-parcelable value.

Add usage docs to the wiki

Include how to parcel a kotlin object too, because it currently isn't called out. E.g.:

@PaperParcel
object State : PaperParcelable {
  @JvmField val CREATOR = PaperParcelable.Creator(State::class.java)
}

Issues with auto value dependency

I'm not using auto value in my project, and it looks like the dependency you require for the compiler doesn't exist:

Error:Could not find com.google.auto:auto-common:1.0-SNAPSHOT.
Searched in the following locations:
https://jcenter.bintray.com/com/google/auto/auto-common/1.0-SNAPSHOT/maven-metadata.xml
https://jcenter.bintray.com/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.pom
https://jcenter.bintray.com/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.jar
https://dl.bintray.com/intercom/intercom-maven/com/google/auto/auto-common/1.0-SNAPSHOT/maven-metadata.xml
https://dl.bintray.com/intercom/intercom-maven/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.pom
https://dl.bintray.com/intercom/intercom-maven/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.jar
https://clojars.org/repo/com/google/auto/auto-common/1.0-SNAPSHOT/maven-metadata.xml
https://clojars.org/repo/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.pom
https://clojars.org/repo/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.jar
https://jitpack.io/com/google/auto/auto-common/1.0-SNAPSHOT/maven-metadata.xml
https://jitpack.io/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.pom
https://jitpack.io/com/google/auto/auto-common/1.0-SNAPSHOT/auto-common-1.0-SNAPSHOT.jar
(...plus my library, removed for privacy)
Required by:
(my app):app:unspecified > com.github.grandstaish.paperparcel:compiler:0.9.8

Update all Javadocs

Some are out of date, especially @PaperParcel

Finish javadocs in the compiler too

Support for arbitrary parceling/unparceling

I'd like to have a generic way to use the generated wrap/getContents methods for a given type. In particular, I'd like a single class that has these two methods (that delegates out to the various generated FooParcel/BarParcel classes):

public static <ORIG, PARCELABLE extends Parcelable> PARCELABLE wrap(ORIG object)
public static <ORIG, PARCELABLE extends Parcelable> ORIG unwrap(PARCELABLE object)

I started implementing this but realized I should check with you first to make sure this is an enhancement you'd be amenable to. Thoughts?

Feedback

Hi,

Here is my feedback trying to understand how to use PaperParcel so far.
In the doc :
val example = Example(42)
val parcelableWrapper = ExampleParcel.wrap(example)

In my project I get ExampleParcel unresolved reference, so I checked the samples but the generated class StateParcel is not used anywhere. If I add StateParcel.wrap(state) in the sample I get the same error. Is there something wrong with the docs / readme ? or did I miss something obvious regarding generated classes? (most likely ; )

Adapters should be re-used for less object instantiation

Currently there is 2 adapter instance created on the fly for each variable that uses an adapter (one for reading, one for writing). There should probably just be one instance of each type of adapter, and that can be used from any parcelable wrapper.

Write a sample app

Simple app showing off regular usage, and also custom usage with TypeAdapters.

Improve 'getter'method selection

Need to ensure that the returned type is the correct type and that the getter method has no parameters. Can also allow for package/public scoped variables to avoid using a getter method at all.

NoClassDefFoundError when upgrading from beta2 to beta3

1.0.0-beta3 fails on run with:

Information:Gradle tasks [clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:prepareDebugUnitTestDependencies, :app:mockableAndroidJar, :app:compileDebugSources, :app:compileDebugAndroidTestSources, :app:compileDebugUnitTestSources]
:app:clean
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2321Library
:app:prepareComAndroidSupportAppcompatV72321Library
:app:prepareComAndroidSupportCardviewV72321Library
:app:prepareComAndroidSupportDesign2321Library
:app:prepareComAndroidSupportRecyclerviewV72321Library
:app:prepareComAndroidSupportSupportV42321Library
:app:prepareComAndroidSupportSupportVectorDrawable2321Library
:app:prepareComGoogleAndroidGmsPlayServicesBase840Library
:app:prepareComGoogleAndroidGmsPlayServicesBasement840Library
:app:prepareComGoogleAndroidGmsPlayServicesGcm840Library
:app:prepareComGoogleAndroidGmsPlayServicesLocation840Library
:app:prepareComGoogleAndroidGmsPlayServicesMaps840Library
:app:prepareComGoogleAndroidGmsPlayServicesMeasurement840Library
:app:prepareComIsseiaokiSimplecropview1016Library
:app:prepareComJakewhartonRxbindingRxbinding040Library
:app:prepareComSquareupSqlbriteSqlbrite062Library
:app:prepareComTrelloRxlifecycle050Library
:app:prepareComTrelloRxlifecycleComponents050Library
:app:prepareDeHdodenhofCircleimageview200Library
:app:prepareIoIntercomAndroidIntercomSdk1116Library
:app:prepareIoIntercomAndroidIntercomSdkBase1116Library
:app:prepareIoIntercomAndroidIntercomSdkGcm1116Library
:app:prepareIoReactivexRxandroid110Library
:app:prepareDebugDependencies
:app:compileDebugAidl
:app:compileDebugRenderscript
:app:generateDebugBuildConfig
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets
:app:generateDebugResValues UP-TO-DATE
:app:processDebugGoogleServices
:app:generateDebugResources
:app:mergeDebugResources
:app:processDebugManifest
:app:processDebugResources
:app:generateDebugSources
:app:preDebugAndroidTestBuild UP-TO-DATE
:app:prepareDebugAndroidTestDependencies
:app:compileDebugAndroidTestAidl
:app:processDebugAndroidTestManifest
:app:compileDebugAndroidTestRenderscript
:app:generateDebugAndroidTestBuildConfig
:app:generateDebugAndroidTestAssets UP-TO-DATE
:app:mergeDebugAndroidTestAssets
:app:generateDebugAndroidTestResValues UP-TO-DATE
:app:generateDebugAndroidTestResources
:app:mergeDebugAndroidTestResources
:app:processDebugAndroidTestResources
:app:generateDebugAndroidTestSources
:app:preDebugUnitTestBuild UP-TO-DATE
:app:prepareDebugUnitTestDependencies
:app:mockableAndroidJar UP-TO-DATE
:app:compileDebugKotlin
:app:compileDebugJavaWithJavac FAILED
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.

java.lang.NoClassDefFoundError: android/os/Parcelable
Information:BUILD FAILED

If I drop down to beta2, everything runs normally. Thoughts?

Improve instantiation strategy

Currently PaperParcel tries to find a valid constructor for re-constructing the data class. It could also look for setter methods, or even a static factory method. This would improve java usage.

Is it possible to make wrap() an extension function?

Started to use your library and this was the first idea that came to me: is it possible to somehow use kapt to generate code which would be recognized as an extension function in Kotlin?

This way one could do:

val example = Example(42)
val parcelableWrapper = Example.wrapInParcel()

which I feel is very convenient.

support kotlin objects

PaperParcel does not currently support Kotlin's object declaration for singletons, i.e. @PaperParcel object MyObject. The PaperParcel compiler will generate code that cannot compile, as it attempts to use the MyObject's private constructor rather than MyObject.INSTANCE.

There are scenarios where it's convenient to be able to mix singleton objects and instances of non-singleton classes, such as in a collection, and parcel them polymorphically. It would be great if PaperParcel could help.

Crash when trying to parcel null properties

Hi again,
When trying to parcel a java class that contains null fields, paper parcel crashes because of NPE.

@PaperParcel
public class HomeScreen {

  HomePresenter.Result result; // result may be null

HomeScreen(HomePresenter.Result result) {
    this.result = result;
  }
}

Generates the following HomeScreen Parcel class:

public final class HomeScreenParcel implements TypedParcelable<HomeScreen> {
  public static final Parcelable.Creator<HomeScreenParcel> CREATOR = new Parcelable.Creator<HomeScreenParcel>() {
    @Override public HomeScreenParcel createFromParcel(Parcel in) {
      return new HomeScreenParcel(in);
    }
    @Override public HomeScreenParcel[] newArray(int size) {
      return new HomeScreenParcel[size];
    }
  };

  private final HomeScreen data;

  private HomeScreenParcel(HomeScreen data) {
    this.data = data;
  }

  private HomeScreenParcel(Parcel in) {
    ResultParcel resultParcel = ResultParcel.CREATOR.createFromParcel(in);
    HomePresenter.Result result = resultParcel.getContents();
    this.data = new HomeScreen(_data_state, result);
  }

  public static final HomeScreenParcel wrap(HomeScreen data) {
    return new HomeScreenParcel(data);
  }

  public HomeScreen getContents() {
    return data;
  }

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    HomePresenter.Result result = data.result;
    ResultParcel resultParcel = ResultParcel.wrap(result);
    resultParcel.writeToParcel(dest, 0);
  }
}

And Result Parcel, when the NPE happens

public final class ResultParcel implements TypedParcelable<HomePresenter.Result> {
  public static final Parcelable.Creator<ResultParcel> CREATOR = new Parcelable.Creator<ResultParcel>() {
    @Override public ResultParcel createFromParcel(Parcel in) {
      return new ResultParcel(in);
    }
    @Override public ResultParcel[] newArray(int size) {
      return new ResultParcel[size];
    }
  };

  private final HomePresenter.Result data;

  private ResultParcel(HomePresenter.Result data) {
    this.data = data;
  }

  private ResultParcel(Parcel in) {
    PlaceParcel placeParcel = PlaceParcel.CREATOR.createFromParcel(in);
    Place place = placeParcel.getContents();
    this.data = new HomePresenter.Result(place);
  }

  public static final ResultParcel wrap(HomePresenter.Result data) {
    return new ResultParcel(data);
  }

  public HomePresenter.Result getContents() {
    return data;
  }

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    Place place = data.getPlace(); // Crashes here because data is null
    PlaceParcel placeParcel = PlaceParcel.wrap(place);
    placeParcel.writeToParcel(dest, 0);
  }
}

Discussion: remove wrap()/getContents() methods

Removing these methods would be a savings of 2 methods per generated class. With Android's 65k dex limit, even these small savings are relevant. This is controversial because it's a breaking change.

The field in the wrapper would be public and final, so it could be accessed without a getter method.

I feel this is OK, because the library aims (for the most part) for these wrappers to go unnoticed using the new PaperParcelable API (or using AutoValue).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.