ButterKnife
と呼ばれる非常に興味深い依存性注入ライブラリに出くわしました。 ButterKnife
を使用すると、ビューをアクティビティまたはフラグメントに簡単に挿入できます。
class ExampleActivity extends Activity {
@InjectView(R.id.title) TextView title;
@InjectView(R.id.subtitle) TextView subtitle;
@InjectView(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
}
ただし、依存性注入を使用する場合は、public
が注入できるようにこれらのビューをButterknife
にする必要があります(private
フィールドを使用すると例外fields must not be private or static
)。
私の過去のプロジェクトでは、これがベストプラクティス(情報隠蔽など)だと思っていたので、常にすべてのメンバーフィールド(ビューを含む)をprivate
にしました。今、すべてを作成しない理由があるかどうか疑問に思っています。ビューpublic
?この場合、ButterKnife
は使用できませんが、コードが大幅に簡略化されるため、使用したいと思います。
まず、ButterKnifeは依存性注入ライブラリではありません。 findViewById
とさまざまなsetXxxListener
呼び出しを置き換えるだけなので、定型的な削減ライブラリと考えることができます。
バターナイフがプライベートではないビューを必要とする理由は、実際にはフィールドを設定するコードを生成するためです。生成されるコードはクラスと同じパッケージに存在するため、フィールドはpackage-private、protected、またはpublicである必要があります。フィールドがプライベートの場合、生成されたコードはプライベートフィールドにアクセスできないため、コンパイルに失敗します。
生成されたコードは次のようになります。
_public static void inject(ExampleActivity target, ExampleActivity source) {
target.title = (TextView) source.findViewById(R.id.title);
target.subtitle = (TextView) source.findViewById(R.id.subtitle);
target.footer = (TextView) source.findViewById(R.id.footer);
}
_
ButterKnife.inject(this)
を呼び出すと、この生成クラスが検索され、inject
のインスタンスをフィールドの宛先とExampleActivity
呼び出しのソースの両方として使用してfindViewById
メソッドが呼び出されます。