面倒臭いので簡単にする
AndroidでParcelableを作るのはいろいろと面倒臭いです。Java言語の仕様的にParcelableインターフェースの必須メソッドを実装するのは仕方がないとしても、項目数が多いとその数だけParcelへのParcelable.CreatorとwriteToParcelを書かないといけないのでかなり手間です。そのParcelable.CreatorとwriteToParcelの部分のコードをAPT(Annotation Processing Tool)で自動生成するツール、CatHandsGendroidを作りました。
どう簡単したいか
一番面倒くさいのはParcelable.CreatorとwriteToParcelのコードを項目ごとに書かないといけないところです。特に項目の数は比較的頻繁に更新しますし、項目を追加したけどそれらのコードを追加し忘れると不具合の原因になります。この面倒臭いところをAPTを使ってCatHandsGendroidに自動生成してもらい、その生成されたコードに繋ぐようにします。
使い方:APTの設定編
導入方法はこちらと同じになります。
使い方:モデルクラスの作成編
手順は次のようになります。
- アノテーションとして「@DataModel(genParcelFunc=true, genDbFunc=false)」を付加する
- 生成されたParcelable.CreatorとwriteToParcelのコードを繋ぐ
例えばこんなモデルクラスがあるとします。
@DataModel(genParcelFunc=true, genDbFunc=false)
public class MyParcelModel {
private String strValue1;
private String strValue2;
private int intValue1;
private int intValue2;
private int doubleValue1;
private int doubleValue2;
/* getterとsetteerは省略 */
}
アノテーションを付けると次のようなコードが生成されます。
public class MyParcelModelCatHands {
public static final IAccessor<String> ACCESSOR_STR_VALUE1;
public static final IAccessor<String> ACCESSOR_STR_VALUE2;
public static final IAccessor<Integer> ACCESSOR_INT_VALUE1;
public static final IAccessor<Integer> ACCESSOR_INT_VALUE2;
public static final IAccessor<Integer> ACCESSOR_DOUBLE_VALUE1;
public static final IAccessor<Integer> ACCESSOR_DOUBLE_VALUE2;
static {
ACCESSOR_STR_VALUE1 = Accessors.StringAccessor.createAccessor(String.class);
ACCESSOR_STR_VALUE2 = Accessors.StringAccessor.createAccessor(String.class);
ACCESSOR_INT_VALUE1 = Accessors.PrimitiveIntegerAccessor.createAccessor(Integer.class);
ACCESSOR_INT_VALUE2 = Accessors.PrimitiveIntegerAccessor.createAccessor(Integer.class);
ACCESSOR_DOUBLE_VALUE1 = Accessors.PrimitiveIntegerAccessor.createAccessor(Integer.class);
ACCESSOR_DOUBLE_VALUE2 = Accessors.PrimitiveIntegerAccessor.createAccessor(Integer.class);
}
public static final android.os.Parcelable.Creator<MyParcelModel> CREATOR = new android.os.Parcelable.Creator<MyParcelModel>() {
@Override
public MyParcelModel createFromParcel(android.os.Parcel in) {
MyParcelModel dest = new MyParcelModel();
readFromParcel(dest, in);
return dest;
}
@Override
public MyParcelModel[] newArray(int size) {
return new MyParcelModel[size];
}
};
public static void readFromParcel(MyParcelModel dest, android.os.Parcel in) {
dest.setStrValue1(ACCESSOR_STR_VALUE1.readFromParcel(in));
dest.setStrValue2(ACCESSOR_STR_VALUE2.readFromParcel(in));
dest.setIntValue1(ACCESSOR_INT_VALUE1.readFromParcel(in));
dest.setIntValue2(ACCESSOR_INT_VALUE2.readFromParcel(in));
dest.setDoubleValue1(ACCESSOR_DOUBLE_VALUE1.readFromParcel(in));
dest.setDoubleValue2(ACCESSOR_DOUBLE_VALUE2.readFromParcel(in));
}
public static void writeToParcel(MyParcelModel src, android.os.Parcel out, int flags) {
ACCESSOR_STR_VALUE1.writeToParcel(out, src.getStrValue1());
ACCESSOR_STR_VALUE2.writeToParcel(out, src.getStrValue2());
ACCESSOR_INT_VALUE1.writeToParcel(out, src.getIntValue1());
ACCESSOR_INT_VALUE2.writeToParcel(out, src.getIntValue2());
ACCESSOR_DOUBLE_VALUE1.writeToParcel(out, src.getDoubleValue1());
ACCESSOR_DOUBLE_VALUE2.writeToParcel(out, src.getDoubleValue2());
}
}
このコードはParcelableを実装するときに必要で面倒臭い原因であるParcelable.CreatorとwriteToParcelのコードを含んでいます。
この2つのコードを元のモデルクラスに繋ぎます。
@DataModel(genParcelFunc=true, genDbFunc=false)
public class MyParcelModel implements Parcelable {
// CREATEを繋ぐ
public static final Creator<MyParcelModel> CREATOR =
MyParcelModelCatHands.CREATOR;
// writeToParcelを繋ぐ
@Override
public void writeToParcel(Parcel dest, int flags) {
MyParcelModelCatHands.writeToParcel(this, dest, flags);
}
@Override
public int describeContents() {
return 0;
}
private String strValue1;
private String strValue2;
private int intValue1;
private int intValue2;
private int doubleValue1;
private int doubleValue2;
/* getterとsetteerは省略 */
}
完成です。
まとめ
項目の数が決まったらParcelable.CreatorとwriteToParcelのコードに何を書くべきか自動的に決まります。しかしAndroidフレームワークはそのコードを生成はしてくれません。いちいち手で書いても良いですが、正直手間ですし、間違えると不具合の原因になります。CatHandsGendroidを使えばその間違えやすい部分を自動で生成してくれます。機械的にできるところはツールに任して、余計な不具合を出さなくて済むようにしましょう。