Skip to content

Commit 9c2e5db

Browse files
natario1flovilmart
authored andcommitted
Parcelable documentation for Android (#428)
* Parcelable reference for ParseObjects * Parcelable referecence for ParseFiles * Parcelable reference for ParseGeoPoint
1 parent be1d5fd commit 9c2e5db

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

_includes/android/files.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,28 @@ file.saveInBackground(new SaveCallback() {
7070
You can delete files that are referenced by objects using the [REST API]({{ site.baseUrl }}/rest/guide/#deleting-files). You will need to provide the master key in order to be allowed to delete a file.
7171

7272
If your files are not referenced by any object in your app, it is not possible to delete them through the REST API. You may request a cleanup of unused files in your app's Settings page. Keep in mind that doing so may break functionality which depended on accessing unreferenced files through their URL property. Files that are currently associated with an object will not be affected.
73+
74+
## Parcelable
75+
76+
As most public facing components of the SDK, `ParseFile` implements the `Parcelable` interface. This means you can retain a `ParseFile` during configuration changes, or pass it to other components of the app through `Bundles`. To achieve this, depending on the context, use either `Parcel#writeParcelable(Parcelable, int)` or `Bundle#putParcelable(String, Parcelable)`. For instance, in an Activity,
77+
78+
```java
79+
private ParseFile file;
80+
81+
@Override
82+
protected void onSaveInstanceState(Bundle outState) {
83+
super.onSaveInstanceState(outState);
84+
if (!file.isDirty()) {
85+
outState.putParcelable("file", file);
86+
}
87+
}
88+
89+
@Override
90+
protected void onCreate(@Nullable Bundle savedInstanceState) {
91+
if (savedInstanceState != null) {
92+
file = (ParseFile) savedInstanceState.getParcelable("file");
93+
}
94+
}
95+
```
96+
97+
Note, however, that files can't be parceled if they are not saved on the server. If you try to do so, an exception will be thrown. If you are not sure if your file has been saved, plaese check for `!isDirty()` to be true before writing it to a parcel.

_includes/android/geopoints.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ query.whereWithinGeoBox("location", southwestOfSF, northeastOfSF);
4242
query.findInBackground(new FindCallback<ParseObject>() { ... });
4343
```
4444

45+
## Parcelable
46+
47+
As most public facing components of the SDK, `ParseGeoPoint` implements the `Parcelable` interface. This means you can retain a `ParseGeoPoint` during configuration changes, or pass it to other components of the app through `Bundles`. To achieve this, depending on the context, use either `Parcel#writeParcelable(Parcelable, int)` or `Bundle#putParcelable(String, Parcelable)`. For instance, in an Activity,
48+
49+
```java
50+
private ParseGeoPoint point;
51+
52+
@Override
53+
protected void onSaveInstanceState(Bundle outState) {
54+
super.onSaveInstanceState(outState);
55+
outState.putParcelable("point", point);
56+
}
57+
58+
@Override
59+
protected void onCreate(@Nullable Bundle savedInstanceState) {
60+
if (savedInstanceState != null) {
61+
point = (ParseGeoPoint) savedInstanceState.getParcelable("point");
62+
}
63+
}
64+
```
65+
4566
## Caveats
4667

4768
At the moment there are a couple of things to watch out for:

_includes/android/objects.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,64 @@ query.findInBackground(new FindCallback<Armor>() {
470470
}
471471
});
472472
```
473+
474+
## Parcelable
475+
476+
As most public facing components of the SDK, `ParseObject` implements the `Parcelable` interface. This means you can retain a `ParseObject` during configuration changes, or pass objects to other components through `Bundle`s. To achieve this, depending on the context, use either `Parcel#writeParcelable(Parcelable, int)` or `Bundle#putParcelable(String, Parcelable)`.
477+
For instance, in an `Activity`,
478+
479+
```java
480+
private ParseObject object;
481+
482+
@Override
483+
protected void onSaveInstanceState(Bundle outState) {
484+
super.onSaveInstanceState(outState);
485+
outState.putParcelable("object", object);
486+
}
487+
488+
@Override
489+
protected void onCreate(@Nullable Bundle savedInstanceState) {
490+
if (savedInstanceState != null) {
491+
object = (ParseObject) savedInstanceState.getParcelable("object");
492+
}
493+
}
494+
```
495+
496+
That's it. `ParseObject` will parcel its internal state, along with unsaved childs and dirty changes. There are, however, a few things to be aware of when parceling objects that have ongoing operations, like save or delete. The SDK behavior differs depending on whether you have enabled the Local Datastore.
497+
498+
### Parceling with Local Datastore enabled
499+
500+
When the Local Datastore is enabled, parceling a `ParseObject` is a safe operation even if there are ongoing save or delete operations. Thanks to LDS, the same instance is returned when unparceling (unless something happens in the middle, in which case the SDK behaves as if LDS was disabled, see below).
501+
502+
This means that the `ParseObject` is internally notified about the operation results, whether it's successful or not. There is, however, no way to register external callbacks (`SaveCallback` or `DeleteCallback`) for these tasks, other than the ones you have already registered at the moment of saving / deleting the source instance.
503+
504+
### Parceling with Local Datastore disabled
505+
506+
When the Local Datastore is disabled, and the parceled `ParseObject` has ongoing operations that haven't finished yet, the unparceled object will end up in a stale state. The unparceled object, being a different instance than the source object,
507+
508+
- assumes that ongoing operations at the moment of parceling never took place
509+
- will not update its internal state when the operations triggered by the source object
510+
511+
The unfortunate consequence is that keys that were dirty before saving will still be marked as dirty for the unparceled object. This means, for instance, that any future call to `saveInBackground()` will send these dirty operations to the server again. This can lead to inconsistencies for operations like `increment`, since it might be performed twice.
512+
513+
### Parceling ParseObject subclasses
514+
515+
By default, `ParseObject` implementation parcels everything that is needed. If your subclasses have stateful information that you would like to keep when parceling, you can simply override `onSaveInstanceState(Bundle)` and `onRestoreInstanceState(Bundle)`:
516+
517+
```java
518+
// Armor.java
519+
@ParseClassName("Armor")
520+
public class Armor extends ParseObject {
521+
private int member;
522+
523+
@Override
524+
protected void onSaveInstanceState(Bundle outState) {
525+
outState.putInt("member", member);
526+
}
527+
528+
@Override
529+
protected void onRestoreInstanceState(Bundle savedInstanceState) {
530+
member = savedInstanceState.getInt("member");
531+
}
532+
}
533+
```

0 commit comments

Comments
 (0)