21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Extra Bindingライブラリの比較

Last updated at Posted at 2016-03-17

導入のモチベーション

Androidでは画面間のデータの受け渡しは、一般的には下のようにIntentにkey-valueを渡して行うと思います。

// FooActivity.java
public static final String KEY = "...";
public static final String KEY = "...";
public static final String KEY = "...";

private String stringValue;
private int intValue;
private boolean booleanValue;

public static void launch(...) {
    ...
    intent.putExtra(KEY, stringValue);
    intent.putExtra(KEY, intValue);
    intent.putExtra(KEY, booleanValue);
    ...
}

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    stringValue = getIntent().getStringExtra(KEY);
    intValue = getIntent().getIntExtra(KEY);
    booleanValue = getIntent().getBooleanExtra(KEY);
    ...
}

これが地味に面倒で、数年前にRoboGuiceを使っていたときは @InjectExtra というのがあり、Extraを自動的にbindできて便利だった(それがDIの範疇に含まれるかはさておき)記憶があるので、似たような機能を提供しているライブラリを探していました。

Extra Binding Libraries

| | ビルドツール | コード生成方法 | Extraの渡し方 | シリアライズ | Fragmentサポート |
|:---|:---|:---|:---|:---|:---|:---|
| dart | maven | apt | use generated class | No | Yes |
| IntentBuilder | gradle | apt | use generated class | No | No |
| PrettyBundle | gradle | apt | use generated class | No | Yes |
| AutoBundle | gradle | apt | use generated class | Yes | Yes |
| injectextra | gradle | apt + bytecode weaving | Intent#putExtra | No | No |

好みの問題もあると思うのですが、私はこの中からコードの品質が良くて仕様を満たしている AutoBundle を選びました。いくつか選定したポイントを書きます。

ビルドツール

何か不都合があったときにPull Requestが送ることができるかは重要ですが、mavenはあまり触りたくなかったので必須ではないですがgradleを使っている方が都合が良かったです。

コード生成方法

どのライブラリもコード生成を行っているのですが、aptで実現できそうなコードでbytecode weavingをするのはメンテすることを考えるとちょっとやりすぎかなという気がします。

Extraの渡し方

Extraを渡される方のクラスはどのライブラリでも bind で値を代入するのですが、渡す側でもできればキーをどこかに書いたりしたくないので Intent#putExtra でなく自動生成して補完が効いたりすると嬉しいですね。たとえば以下のようなクラスだと

// FooActivity.java
public static final String KEY = "...";
public static final String KEY = "...";
public static final String KEY = "...";

private String stringValue;
private int intValue;
private boolean booleanValue;

public static void launch(...) {
    ...
    intent.putExtra(KEY, stringValue);
    intent.putExtra(KEY, intValue);
    intent.putExtra(KEY, booleanValue);
    ...
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    stringValue = getIntent().getStringExtra(KEY);
    intValue = getIntent().getIntExtra(KEY);
    booleanValue = getIntent().getBooleanExtra(KEY);
    ...
}

AutoBundleでは @AutoBundleField を付けることで #{class_name}AutoBundle クラスが生成されます。必須のパラメータはコンストラクタに、必須でないパラメータはビルダーのメソッドに渡すことができます。

// FooActivity.java
@AutoBundleField String stringValue;
@AutoBundleField int intValue;
@AutoBundleField(required = false) boolean booleanValue;

public static void launch(...) {
    ...
    FooActivityAutoBundle.createIntentBuilder(stringValue, intValue)
        .booleanValue(booleanValue)
        .build(context);
    ...
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FooActivityAutoBundle.bind(this, getIntent());
    ...
}

シリアライズ

たとえばUserオブジェクトを渡すのに対応している型にシリアライズして、onCreateの中でデシリアライズしてとかだと面倒なので、自動で変換を行ってくれると嬉しいです。AutoBundleでは @AutoBundleField(converter = *.class) で変換を行うクラスを指定することができます。

@AutoBundleField(converter = UserConveter.class)

Fragmentサポート

Fragment用のbindingライブラリもありますが(sockeqwe/fragmentargs: Annotation Processor for setting arguments in android fragments)、できれば一つのライブラリでActivityとFragmentを統一的に扱えた方が学習コストが低くなって嬉しいです。

というわけで私はAutoBundleを使っています。

21
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?