Enhanced componentsとは直訳すると強化された部品という意味で、AndroidAnnotations(以下AA)を使用することが出来るクラスです。具体的には以下のものがあります。
ViewのInjectについて – AndroidAnnotations
@ViewById
Viewクラスが型のメンバ変数に対して@ViewByIdをつけるとレイアウトからfindViewByIdのメソッドが代入された状態になります。
ResourcesのInject – AndroidAnnotations
@XXXResのアノテーションはresフォルダのリソースをメンバ変数にInjectすることが出来ます。
Injectされるリソースはアノテーションの後ろにidを書くことで指定できます。idの指定が無い場合はメンバ変数名を元に決定されます。
またメンバ変数はprivate修飾子をつけるとうまく動作しません。
@StringRes
指定したIDのStringリソースをメンバ変数にInjectします
@EActivity public class MyActivity extends Activity { // R.string.helloがmyHelloStringにInjectされます @StringRes(R.string.hello) String myHelloString; // IDの指定が無い場合メンバ変数名のhelloを元に、R.string.helloがInjectされます @StringRes String hello; }
<li>
@ColorRes
</li>
<li>
@AnimationRes
</li>
<li>
@DimentionRes
</li>
<li>
@DimentionPixelOffsetRes
</li>
<li>
@DimentionPixelSizeRes
</li>
<li>
@BooleanRes
</li>
<li>
@ColorStateListRes
</li>
<li>
@DrawableRes
</li>
<li>
@IntArrayRes
</li>
<li>
@LayoutRes
</li>
<li>
@MovieRes
</li>
<li>
@TextRes
</li>
<li>
@TextArrayRes
</li>
<li>
@StringArrayRes
</li>
</ul>
EViewGroupについて – AndroidAnnotations
@EViewGroupはViewModelのバインディングでコードを整理出来るのでとても気に入っています
まずはViewのレイアウトを作成します。
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" > <ImageView android:id="@+id/image" android:layout_alignParentRight="true" android:layout_alignBottom="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/check" /> <TextView android:id="@+id/title" android:layout_toLeftOf="@+id/image" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="12pt" /> <TextView android:id="@+id/subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/title" android:textColor="#FFdedede" android:textSize="10pt" /> </merge>
TitleWithSubtitle_クラスは先ほど書いたsetTextsメソッドで簡単に文字列を変更できます
public class Main extends Activity { @ViewById protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle; @AfterViews protected void init() { firstTitle.setTexts("decouple your code", "Hide the component logic from the code using it."); secondTitle.setTexts("write once, reuse anywhere", "Declare you component in multiple " + "places, just as easily as you " + "would put a single basic View."); thirdTitle.setTexts("Let's get stated!", "Let's see how AndroidAnnotations can make it easier!"); } }
setTexts(String, String)のように複数の引数で渡してあけることも出来るし, setModel(Model)みたいに、モデルごと渡してあげることもできるので、コントローラー側のコードがスッキリしてよい
EViewについて – AndroidAnnotations
Viewの継承クラスに@EViewをつけるとAndroidAnnotationswを使い始めることが出来ます。
<pre class="brush: java; gutter: true">@EView
public class CustomButton extends Button {
@App MyApplication application;
@StringRes String someStringResource;
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
<p>
Layout XMLの中でも利用することが出来ます
</p>
<div>
<div id="highlighter_847993">
<pre class="brush: xml; gutter: true"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.androidannotations.view.CustomButton_
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<p>
</p>
</div>
<p>
</p>
</div>
<p>
プログラム内で利用するには以下のようにします
</p>
<div>
<div id="highlighter_920845">
<pre class="brush: java; gutter: true">CustomButton button = CustomButton_.build(context);</pre>
EFragmentについて – AndroidAnnotations
fragmentでAndroidAnnotations(以下AA)を利用するには次のようにします
@EFragment public class MyFragment extends Fragment { }
fragmentもActivity同様に_のsuffixが入ります。なので利用する時はMyFragment_のようにアンダースコアを追加してください。
例えばXMLで利用する場合は次のようになります。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <fragment android:id="@+id/myFragment" android:name="com.company.MyFragment_" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
またJavaのコード上では次のように利用できます
<pre class="brush: java; gutter: true">MyFragment fragment = new MyFragment_();</pre>
JsonPullParserのJsonModelを取得するVolleyのRequestをつくってみた
JsonPullParserのJsonModelを取得するVolleyのRequestをつくってみました。
Volleyとは?
Google I/O 2013で発表されたすごいAndroidの通信ライブラリ。どうすごいかは以下のリンクが参考になります。
Google I/O 2013 – Volley: Easy, Fast Networking for Android
Y.A.Mの雑記帳: Google I/O 2013 – Volley: Easy, Fast Networking for Android
JsonPullParserとは?
JSONとPOJOを相互変換するライブラリです。APTの仕組みを利用しています。
https://github.com/vvakame/JsonPullParser
つくったもの
https://github.com/fly1tkg/volley-jpp-request
使い方
Volleyと上記のレポジトリのjarにパスをとおして、あとはこんな感じです。
mQueueRequest = Volley.newRequestQueue(this); mQueueRequest.add(new JsonModelRequest<Sample, SampleGen>(JSON_URL, new Listener<Sample>() { @Override public void onResponse(Sample sample) { mJsonTextView.setText(sample.toString()); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); } }));
パフォーマンスとか
このライブラリは内部でリフレクションを利用しているので、若干パフォーマンスが悪いです。(気になるレベルでは無いと思いますが)
リフレクションを利用した理由としてJPPでinterfaceのimplementやクラス継承が使われておらず、Genクラスのget(string json)メソッドを呼び出しつつ、ジェネリクスを利用した柔軟なクラスを作れなかったからです。JPPのアプローチから言うと、おそらくマーカーアノテーションで指定したJsonModelに対して、VolleyのRequestをAPTで生成するというアプローチがよいと思うのですが、、、、めんどくさかったんです、、、。
ジェネリクスからリフレクションを利用する方法として、黒魔術ですが、Java変態文法最速マスターの4を利用しました。
事前準備 AndroidAnnotations
AndroidAnnotations(以下AA)のライブラリをAndroidのプロジェクトに適用する方法を説明します。
公式のWikiにはMavenやAnt、Gradleといったビルドツールを用いた方法も書かれていますが、ここでは普通のビルドツールを使わない方法を説明します。
1. ダウンロード
以下のリンクから最新版をダウンロード出来ます
https://github.com/excilys/androidannotations/wiki/Download
2. Eclipseに設定する
事前にAndroidプロジェクトのJavaの設定がjava 1.6になっていることを確認してください。
確認方法はEclipseのPackage Exploreで確認したいAndroidプロジェクトで右クリックしてPropertiesをクリック、Java compilerの項目でCompiler compliance levelの部分が1.6になっていればOKです。
先ほどのダウンロードリンクからダウンロードしたファイルのうちandroidannotations-X.X.X-api.jarをlibsフォルダに置きます
またandroidannotations-X.X.X.jarはcompile-libsなどlibsフォルダとは違うフォルダを作成して、そのフォルダに置きます
Package Exploreで確認したいAndroidプロジェクトで右クリックしてPropertiesをクリックし、Propertiesを表示します。
Java Compiler –> Annotation Processingを選択しEnable annotation processingにチェックを入れます
Java Compiler –> Annotation Processing –> Factory PathでAdd jarsボタンをクリックし、androidannotations-X.X.X.jarのパスをを入力します
ADT16以前であればJava Build Path –> Librariesでandroidannotations-X.X.X-api.jarのパスを追加してください。ADTが最新であれば問題ありません。
準備完了
これで全ての準備が完了です。AAが使えるようになります。
基本的な使い方 AndroidAnnotations
AndroidAnnotations(以下AA)の基本的な使い方を説明します。
AAの設定がされていない場合は以下のリンクを参考に設定してください。
事前準備 AndroidAnnotations | b.fly1tkg.com
@EActivityをつける
AAをActivityで使用するにはクラスに@EActivityをつける必要があります。
@EActivity public class MyActivity extends Activity {
そしてAndroidManifest.xmlへのActivityの登録は_のsuffixが必要になります。
<activity android:name=".MyActivity_" />
これは上記の例で言うとMyActivityを継承したMyActivity_というクラスがAAによって生成され、MyActivity_で色々と便利なコードが生成されるからです。
AAでHelloWorld
次のようなコードでAAを使ったHello Worldを作成することが出来ます。
詳しくはEActivityのエントリーで説明します。
MyActivity.java
@EActivity(R.layout.main) public class MyActivity extends Activity { @ViewById(R.id.myInput) EditText myInput; @ViewById(R.id.myTextView) TextView textView; @Click void myButton() { String name = myInput.getText().toString(); textView.setText("Hello "+name); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <EditText android:id="@+id/myInput" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/myButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Click me!" /> <TextView android:id="@+id/myTextView" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
まず@EActivity(R.layout.main)でres/layout/main.xmlのレイアウトを適用出来ます。
また@ViewById(R.id.myTextView)でmain.xmlのidがmyTextViewのTextViewのインスタンスが自動的に代入されます。これでfindViewById(R.id.myTextView)といったコードを書かなくてもよいです。
@Clickはメソッド名と同じIDのViewがクリックされたときの処理を指定しています。ここではmyButtonがクリックされた時にmyTextViewにテキストを表示することをしています。@Click(R.id.myButton)のようにIDを指定することも出来ます。
EActivityについて – AndroidAnnotations
@EActivityのアノテーションをつけることでそのActivity内でAndroidAnnotations(以下AA)が使えるようになります。以下のようにActivityに@EActivityをつけます。
@EActivity(R.layout.main) public class MyActivity extends Activity { }
ListActivityなどレイアウトを指定しない場合はそのままつければOKです。
@EActivity public class MyListActivity extends ListActivity { }
@EActivityをつけると元のクラスを継承し、_のsuffixがついたコードが生成されます。そのためAndroidManifest.xmlに登録する際は最後に_をつけます。
<activity android:name="MyActivity_"/>
IntentBuilder
EActivityではAAが使える以外に特徴的なこととして、IntentBuiderというものが自動で生成されるということです。
例えば通常ActivityにIntentする時は以下のようなコードを書くと思います。
Intent i = new Intent(this, MyActivity.class); startActivity(i);
このIntentBuilderを使うと次のような書き方が出来ます。
new MyActivity_.IntentBuilder_(this).start();
IntentBuilderよってIntentでの値の受け渡しは、@Extraがついたデフォルトのメンバ変数に対してsetterが準備されます。
以下のようなMainActivityに遷移使用とする時
@EActivity(R.layout.activity_main) public class MainActivity extends Activity { @Extra String name; @Extra int id; }
Intentするためのコードは以下のようになります。
new MainActivity_.IntentBuilder_(this) .name("answer") .id(42) .start();
IntentのFlagもセットすることも出来ます
new MainActivity_.IntentBuilder_(this) .flags(Intent.FLAG_ACTIVITY_CLEAR_TOP) .start();