PARCELABLE INTERFACE OVERVIEW

In one of my earlier posts, I mentioned writing an article about FOSOAuthBundle integration with an Android client. To keep that article to the point, I need to explain some concepts beforehand. One of the important concepts is the Android Parcelable interface that allows data to be transferred between different processes/threads. Certain network operations with Android such as authentication with OAuth2 and then fetching data from a REST endpoint should be performed in the background in order not to block the UI thread. This requires data to be fetched by a service (I have opted for Intent Services in my implementation) in the background and then passed back to the calling activity/fragment with a result callback. This is where the Parcelable interface comes into play.

Basically, theParcelableinterface allows your classes to be flattened inside a message container called aParcelto facilitate high performance inter process communication. The received parcel data can then be unflattened to generate object/entity instances.

A BASIC PARCELABLE EXAMPLE

A Parcelable implementation is pretty straight forward. Override the necessary methods called writeToParcel() and describeContents(), add a static field called CREATOR which generates instances of your Parcelable class from a Parcel, and overload the class constructor which expects a Parcel as a parameter and calls the readFromParcel() utility method. Here is a basic example:

view plain print ?
  1. publicclassConversationimplementsParcelable{
  2. //...
  3. protectedStringlastComment;
  4. protectedIntegermessageCount;
  5. protectedDatecreatedAt;
  6. //...
  7. //...
  8. publicConversation(Parcelin){
  9. readFromParcel(in);
  10. }
  11. @Override
  12. publicvoidwriteToParcel(Parcelout,intflags){
  13. //...
  14. out.writeString(lastComment);
  15. out.writeInt(messageCount);
  16. out.writeSerializable(createdAt);
  17. //...
  18. }
  19. privatevoidreadFromParcel(Parcelin){
  20. //...
  21. lastComment=in.readString();
  22. messageCount=in.readInt();
  23. createdAt=(Date)in.readSerializable();
  24. //...
  25. }
  26. publicstaticfinalParcelable.Creator<conversation>CREATOR=newParcelable.Creator<conversation>(){
  27. publicConversationcreateFromParcel(Parcelin){
  28. returnnewConversation(in);
  29. }
  30. publicConversation[]newArray(intsize){
  31. returnnewConversation[size];
  32. }
  33. };
  34. @Override
  35. publicintdescribeContents(){
  36. return0;
  37. }
  38. }
  39. </conversation></conversation>

NESTED PARCELABLE CLASSES

Lets say we have a Conversation class instance with an embedded User class instance that holds some information about a user that has initiated the conversation. Basically, we are talking about an one-to-one embedded mapping. In this case, if thefromUserproperty holds a User instance, then writing the user data to parcel would be accomplished as shown below:

view plain print ?
  1. @Override
  2. publicvoidwriteToParcel(Parcelout,intflags){
  3. //...
  4. out.writeParcelable(fromUser,flags);
  5. //...
  6. }

Reading the user data from parcel:

view plain print ?
  1. privatevoidreadFromParcel(Parcelin){
  2. //...
  3. fromUser=in.readParcelable(User.class.getClassLoader());
  4. //...
  5. }

If you have a one-to-many embedded relationship such as a list of messages in a conversation, then the syntax would change as follows:

view plain print ?
  1. @Override
  2. publicvoidwriteToParcel(Parcelout,intflags){
  3. //...
  4. out.writeList(messages);
  5. //...
  6. }

Reading from the parcel:

view plain print ?
  1. privatevoidreadFromParcel(Parcelin){
  2. //...
  3. in.readList(messages,Message.class.getClassLoader());
  4. //...
  5. }

BOOLEAN TYPES

Android API does not have a method to write a single boolean value to a parcel. In this case, you can utilize the writeInt() method as shown below:

view plain print ?
  1. @Override
  2. publicvoidwriteToParcel(Parcelout,intflags){
  3. //...
  4. out.writeInt(booleanValue?1:0);
  5. //...
  6. }

Reading from the parcel:

view plain print ?
  1. privatevoidreadFromParcel(Parcelin){
  2. //...
  3. booleanValue=in.readInt()==1;
  4. //...
  5. }

ENUM TYPES

To flatten an Enum type in a parcel, simply implement the Parcelable interface for the Enum type. Here is an example:

view plain print ?
  1. publicenumStatusimplementsParcelable{
  2. STARTED,PAUSED,FINISHED;
  3. publicstaticfinalParcelable.Creator<status>CREATOR=newParcelable.Creator<status>(){
  4. publicStatuscreateFromParcel(Parcelin){
  5. returnStatus.values()[in.readInt()];
  6. }
  7. publicStatus[]newArray(intsize){
  8. returnnewStatus[size];
  9. }
  10. };
  11. @Override
  12. publicintdescribeContents(){
  13. return0;
  14. }
  15. @Override
  16. publicvoidwriteToParcel(Parcelout,intflags){
  17. out.writeInt(ordinal());
  18. }
  19. }
  20. </status></status>

When writing to the parcel, treat it as a nested Parcelable class:

view plain print ?
  1. @Override
  2. publicvoidwriteToParcel(Parcelout,intflags){
  3. //...
  4. out.writeParcelable(status,flags);
  5. //...
  6. }

Reading from the parcel:

view plain print ?
  1. privatevoidreadFromParcel(Parcelin){
  2. //...
  3. status=in.readParcelable(Status.class.getClassLoader());
  4. //...
  5. }

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. php安全问题思考
  2. PHP——命名空间(namespace)使用详细介绍
  3. mac下多个php版本切换(可操作版)
  4. TP5框架下MySQL通过LOAD DATA INFILE批量
  5. 关于PHP中闭包的详细讲解(附详细实例)
  6. 关于Https原理的个人理解分享
  7. form表单在PHP中的实现方式
  8. 利用for循环实现excel中多列数据合并到一
  9. PHP 常用命令行
  10. PHP实时生成并下载超大数据量的EXCEL文件