Wednesday, February 18, 2015

MyNotes: Building the Data Access Layer

Now the groundwork is laid, I can create my actual data access layer.  This basically consists of two classes : Note, and NotesManager.

Note

The Note class is a glorified POJO.  It is a very simple data object with 3 attributes:
  •  a long identifier that is defaulted to -1
  •  a non-null String text object to contain the note text.  This is defaulted to an empty String.
  •  a non-null NoteColor that is the color for the note. This defaulted to the yellow color.
It also has the associate getter and setters for each attribute.

The glorified piece comes from the two interfaces it implements: DatabaseStorable (discussed in the previous post) and Parcelable.  This makes the note aware of the Database so that it can update/delete its backing data.  The Parcelable interface means that the data can be marshalled into a Parcel.

What is Parceling?


Serialization in Android is very slow.  As a result, they created another way to marshal data in an efficient way.  It is very simple to implement, but remember that order matters.  To marshal the Note I only have two implement the writeToParcel method:

@Override
    public void writeToParcel(final Parcel dest, final int flags) {
        dest.writeLong(mId);
        dest.writeString(mText);
        dest.writeInt(mColor.ordinal());
    }

Then I implement a special constructor that takes in a Parcel object:

    public Note(Parcel source) {
        mId = source.readLong();
        mText = source.readString();
        mColor = NoteColor.getColor(source.readInt());
    }

Like I said earlier, order matters.  The order that the data is written into the Parcel is the order that it must be read back out.  No deviations.  Parcel objects can contain other Parcelable objects easily. There are complications when it comes to complex types like Maps.  The maps have to be broken down into component pieces in order to be stored.  It is then reassembled in the constructor.

I also a created some boilerplate code that is common to Parcelable objects.  It gives users of the Parcelable data more options for using the object.  That boilerplate is :

public static final Parcelable.Creator<Note> CREATOR = new Parcelable.Creator<Note>() {
        @Override
        public Note createFromParcel(final Parcel source) {
            return new Note(source);
        }


        @Override
        public Note[] newArray(final int size) {
            return new Note[0];
        }
    };



So Why Parcel?

There are a lot reasons, but the biggest is too allow the objects state to be stored in a Bundle.  This means that a copy of the object can be passed between Activities, Fragments, Services, etc via the Intent Bundle.  It also lets the object be stored in the save instance bundle in Activities and Fragments.  This will make things a lot easier when I get to the UI levels.

The Caveat

If the parcel is going to be passed in an Intent, you must watch the size carefully. It cannot exceed 1MB.  If it goes over, your app can hang and then crash.  This is due to a annoying size constraint in the OS.

Luckily, the size constraint problem does not exist if the parcel is going into a save state bundle to preserve the state of an Activity or Fragment.

I didn't mention in the database entry, but the same size issue can exist there as well.  It will let you store blobs over 1MB, but good luck on getting it back out because the Cursor class does not like to exceed that limit.

NotesManager

This is a pretty straightforward class. It is the way I will create Note objects from the database.  It provides methods to get all of the notes, or get the notes with certain colors, or get a single note.  That is pretty much it.

Commits

I did some of the development for these changes late at night after a busy week so it is broken into two commits:

No comments :

Post a Comment