読んだ: Effective Android
- 作者: TechBooster,小太刀御禄,出村成和,重田大助,西岡靖代,宮川大輔,柏本和俊,あんざいゆき,八木俊広,木村尭海,小林慎治,有山圭二,中西良明,わかめまさひろ,新井祐一,桝井草介,久郷達也,寺園聖文,shige0501,山下智樹,前田章博,秋葉ちひろ,末広尚義,中澤慧,日高正博,塚田翔也,井形圭介,中川幸哉,山崎誠,山下武志,なまそで,橋爪香織,さとうかずのり,l_b__,ゼロハチネット,長汐祐哉
- 出版社/メーカー: インプレスジャパン
- 発売日: 2014/01/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (7件) を見る
読みました。 タイトルからは 『Effective C++』 や 『Effective Java』 が連想されますね。 副題として 「アプリケーション開発を効率化する 39 のテクニック集」 と表紙に書かれています。
Effective Android - 達人出版会内容紹介
Androidの機能・端末バリエーションは年々巨大化しています。おぼろげな理解でも試行錯誤によってある程度のことが実現出来ますが、安定動作するアプリ、使っていて気持ちの良いアプリに仕上げる上では、依然きちんと理解する必要のあることが多く存在します。
本書は、Androidアプリ開発へ携わる著者総勢20名によるデザイン/開発上のポイント集です。
日々の開発中にぶつかった問題を掘り下げたもの、Androidのソースコードを読み解くことで得られたもの、多くの端末サイズ/解像度へと対応する中で得られたもの、Googleサービス群と連携する中で得られたものなど、日々のアプリ開発を一歩先へと進めるヒントに満ちていることでしょう。
上記内容紹介にかかれているように、本書は複数人によって書かれた書籍です。 もともと同人誌として発行されていたものなので、わりと各自が好きなことを書いてるようで、基本的には章ごとの体系だった流れのようなものはありません。 ある程度分野ごとに章はまとまっていますし、関連する章が前後に並んでいたりはしますが、基本的にはそれぞれの章を独立に読む、という感じの読み方になるでしょう。
カード UI の実現の仕方や、カード UI にアニメーションを付ける方法、といったすぐに使える UI 上のチップスもあれば、Eclipse の設定ファイルの話や Gradle の話といった開発環境周りの話、SQLite や NFC といったミドルウェア (?) 的な話、便利ライブラリの紹介、それから NDK などのプラットフォーム周りの話といった感じで、内容は多岐にわたっています。
以前、Maven Central Repository への AAR パッケージのアップロード方法を書きましたが、それと同様の内容も本書に収録されてました。
さらには、Git についての話や Java 7、Java 8 の話も書かれています。 Git については、write-tree
コマンドや rev-parse
コマンドといったマニアックなコマンドが紹介されていて、普段 Git を使っている人でも 「ほえー」 ってなるかもしれません *1。 Java 7 の話については、API level 19 以降では Java 7 の構文をフルで使えるようになった *2 といったことが書かれていて、そういうことを知らない人にはいろいろ得るところがあると思いますし、Java 8 についてもいろいろ書かれていて勉強になります *3。
感想
内容が多岐にわたっており、また、結構マニアックな話題も多いので、いろいろ視野が広がって良かったです。 たとえば、NFC タグの話や SQLiteDatabase の WAL の話、オーディオ周りの話などは 「へー」 という感じで読みました。 普段業務で Android アプリを開発していたり、個人で Android アプリを開発している人で、自分が普段関わらないようなところも含めてチップス集を読みたい、という気持ちがあれば本書はオススメです。 すぐさま業務に活かせるようなチップスもありますし (そうでないものもあります)、読み物としても興味深く読めるでしょう。
一方で、体系だった章立てになっていないという点や、全体的に誰しもにすぐ役立つ情報が多くないという点から、一通り Android アプリ開発できるようになった人に 「とりあえず読め!」 って感じで薦められる本ではないです。 あえてこういうことを書くのは、『Efefctive C++』 や 『Effective Java』 とタイトルが似てるからです *4。
読み物的な感じで Android アプリに関して視野を広げたい、って人にお勧めです。
EFFECTIVE JAVA 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2014/03/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
『Effective Java』 もお薦めです。
Annotations Support Library が Android Studio 0.5.5 でサポートされた
Annotations Support Library の概要
ちゃんとしたドキュメントが見当たらないのですが、 *1 Android Support library のリビジョン 19.1.0 から、新たに Annotations Support Library が追加されました。 このライブラリは、その名のとおり Android アプリ開発時に用いることができるアノテーションの集まりです。 例えば、@NonNull
や @Nullable
といったアノテーションが含まれています。
さらに、Android Studio ではバージョン 0.5.5 からこれらのアノテーションをサポートしており、アノテーションを使うことでいろいろと警告を出してくれるようになっています。
Support for the new annotations which shipped with the most recent version of the support library, such as
Android Studio 0.5.5 Released - Android Tools Project Site@NonNull
and@Nullable
, as well as annotations to declare resource types and valid constants. Add a dependency oncom.android.support:support-annotations:+
to use these in your projects. In the upcoming 0.10.x version of the Android Gradle plugin, the plugin will extract these annotations into your libraries' AAR files such that clients of your library can get the same resource type checks as is shown above for the SDK APIs.
Android Support library については前に記事を書きましたので、合わせて参照ください。
Support Annotation についての公式的なドキュメントは次のページをご覧ください。
Annotations Support Library の使い方
ビルドシステムに Gradle を使っている場合についての説明です。
Android SDK Manager で 「Android Support Repository」 (リビジョン 5 以上) をインストールしたうえで、build.gradle に次のように記述することで Annotations Support Library を使用できます。
dependencies { compile 'com.android.support:support-annotations:22.2.0' // バージョン番号は必要に応じて変更してください。 }
使用できるアノテーション紹介
どういうアノテーションがあるのかを紹介します。 バージョン 19.1.0 時点での情報ですので、新しいバージョンでは使用できるアノテーションが増えているかもしれません。
@NonNull
と @Nullable
これらは、メソッドの返り値が null
になりうるかどうかや、メソッドのパラメータとして null
を許容するかどうか、といったことを表すのに用いられます。
private void displayName(@NonNull String name) { // ... }
例えば、引数として null
を許容しないメソッドを定義する場合、上のように @NonNull
アノテーションを用いて null
を許容しないことを表現できます。
そして、そのように定義されたメソッドの呼び出し時に null
を引数として渡すようなコードを書くと、Android Studio 上で次のように警告が表示されます。
私は null
になりうる変数には xxxOrNull
みたいな名前を付けるといった命名規則などで null
周りのバグを減らすように気を付けたりしているのですが、アノテーションと IDE によるサポートがあると便利で良さそうですね。
どの種類のリソースを参照するための int
値なのかを示すアノテーション
Android アプリで使用する各種リソースは int
値で参照されます。 どの種類のリソースでも同じ int
型で表されるので、Drawable のリソース ID を受け取るメソッドに、Drawable 以外のリソースの ID を渡すといったことや、そもそもリソースの ID でない単なる数値を渡すといったことも (コード上は) 可能です。
Annotations Support Library には、どの種類のリソースの ID なのかを示すためのアノテーションも含まれています。 例えば、Drawable リソースであることを示すアノテーションは @DrawableRes
アノテーション です。
private void receiveDrawableRes(@DrawableRes int resId) { // ... }
例えば、引数として Drawable リソースの ID を受け取るメソッドを定義する場合、上のように @DrawableRes
アノテーションを付けて、引数が Drawable リソースの ID であることを示せます。
このメソッドに Drawable 以外のリソースの ID を渡すと、次のように Android Studio がエラー表示してくれます。
@DrawableRes
アノテーションの他にも、@AnimRes
や @ColorRes
、@StringRes
といった、各種リソースに対応したアノテーションが存在します。
@IntDef
と @StringDef
定数として定義したいくつかの int
型 (あるいは String
型) の値のうちのいずれかを引数として受け取るメソッドを書きたい、ということがままあります。 そんなときに便利なのがこれらのアノテーションです。
普通にメソッドを定義すると、任意の int
値を受け取れるようになってしまいますが、これらのアノテーションを用いて独自のアノテーションを定義することで、メソッドが指定の定数のみを受け取ることを示すことができます。
@IntDef
アノテーションを用いて、独自のアノテーション (@NavigationMode
アノテーション) を定義する例は次のような感じです。
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) public @interface NavigationMode {} public static final int NAVIGATION_MODE_STANDARD = 0; public static final int NAVIGATION_MODE_LIST = 1; public static final int NAVIGATION_MODE_TABS = 2;
そして、上で定義されたアノテーションを使い、NAVIGATION_MODE_STANDARD
、NAVIGATION_MODE_LIST
、NAVIGATION_MODE_TABS
のいずれかの値を受け取るメソッドであることを次のように示せます。
private void navigate(@NavigationMode int navMode) { // ... }
呼び出し時には定数を使って値を指定しないと、次のようにエラーが表示されます。
まとめ
Android Support library のリビジョン 19.1.0 で Annotations Support Library が追加され、Android Studio 0.5.5 でそれらのアノテーションがサポートされました。
著しく開発効率が上がったり、本質的な機能の向上があるわけではなく、あくまで開発の補助に使用できるものではありますが、地味に便利だと思います。 せっかく Android Studio でこのようなアノテーションがサポートされたのですから使っていきましょう!
- 作者: TechBooster,小太刀御禄,出村成和,重田大助,西岡靖代,宮川大輔,柏本和俊,あんざいゆき,八木俊広,木村尭海,小林慎治,有山圭二,中西良明,わかめまさひろ,新井祐一,桝井草介,久郷達也,寺園聖文,shige0501,山下智樹,前田章博,秋葉ちひろ,末広尚義,中澤慧,日高正博,塚田翔也,井形圭介,中川幸哉,山崎誠,山下武志,なまそで,橋爪香織,さとうかずのり,l_b__,ゼロハチネット,長汐祐哉
- 出版社/メーカー: インプレスジャパン
- 発売日: 2014/01/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (8件) を見る
変更履歴
- 2015-06-13 : 「support-annotations ライブラリ」 と記述していたのを 「Annotations Support Library」 に変更。
*1:最近公式的なドキュメントも書かれました。
読んだ: 高速スケーラブル検索エンジン ElasticSearch Server
高速スケーラブル検索エンジン ElasticSearch Server
- 作者: Rafal Kuc,Marek Rogozinski,株式会社リクルートテクノロジーズ,大岩達也,大谷純,兼山元太,水戸祐介,守谷純之介
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2014/03/21
- メディア: 大型本
- この商品を含むブログ (2件) を見る
2014 年 3 月末に発売された Elasticsearch の本を読み終えました。 私が知る限り、現在のところ唯一の日本語で書かれた Elasticsearch に関する書籍です。 書籍の題では 「ElasticSearch」 という表記が使われていますが、これはバージョン 0.90.x 系までの表記で、バージョン 1.0 からは 「Elasticsearch」 (s が小文字) という表記になっているようです。
本書は、ElasticSearch 0.90.11 を対象として書かれていますが、基本的にはバージョン 1.0 以降でも通用します。
対象読者、全体的な内容
本書の序文にも書かれているように、全文検索の初心者、あるいは Elasticsearch の初心者向けの書籍です。
Elasticsearch とは何か、どうやって使用するのか、という最初の一歩の部分からはじまり、データのインデキシングの方法や検索クエリの組み立て方といった検索機能全般について、クラスタ監視やシャードとレプリカの配置制御といったインフラ寄りの話、それからプラグインについての話など、Elasticsearch の基礎的なことが網羅的に記述されています。
コマンドラインから curl
コマンドを実行することができて、JSON を知っている、というぐらいの知識さえあれば、本書を読み進めていくことができると思います。
感想
私自身は去年 (2013 年) から Elasticsearch を使っていました。 去年の段階では本書も発売されていませんでしたし、他に良い書籍もありませんでしたので、公式サイトのリファレンスを見て学んでいました。
- 公式サイトのリファレンス: Elasticsearch のリファレンス
しかしながら、主にクエリ DSL について調べていたという理由や、英語であるためざっと流し読みするということが難しかったという理由などもあり、公式リファレンスだけでは網羅的な Elasticsearch の知識を得ることができていませんでした。
そんなわけなので私はそこそこ公式リファレンスの知識を持った状態で本書を読み始めたのですが、初心者向けに書かれているだけあって本書の方が公式リファレンスよりもわかりやすく書かれているように思いました。 (日本語だからというのもあるとは思いますが。) 訳も読みやすくて、基本的にはよくわからなくて困るということもないでしょう。
(ただ、下の部分だけはいまだによくわかっていません。 そのうちちゃんと調べます...。)
『fuzzy like this クエリは more like this クエリに似て (略) しかし、more like this クエリとは異なる動作をします。 なぜなら、fuzzy 文字列を使うと、提示された単語ともっとも異なる単語を選択するからです』 って
— nobuoka (@nobuoka) 2014, 4月 21
って 2.4.9 節に書かれているけど、これあってるんだろうか。 (もっとも異なる単語を選択とは??)
高速スケーラブル検索エンジン ElasticSearch Server http://t.co/BzuY6pACKk
— nobuoka (@nobuoka) 2014, 4月 21
本書を最初から最後まで読むことで、Elasticsearch の基礎について網羅的に学べました。 これから Elasticsearch を使うから基礎的なことを網羅的に学びたい、という人は本書を読むといいと思います!
JAX-RS アプリケーションで PreMatching フィルタを使ってリクエスト URL を書きかえる
JAX-RS アプリケーションを書いているときに、リクエストされた URI のパスを書きかえて、対応するリソースを書き替えたい場合があります。 そのような時には、PreMatching フィルタを使用できます。
- JAX-RS 2.0 のドキュメント: JSR-000339 JAX-RS 2.0 - Final Release
- フィルタについては 6.2 節 「Filters」 に書いてあります。
- Jersey の Filter のドキュメント: Chapter 9. Filters and Interceptors
例えば、リクエスト URI のパスがスラッシュで終わっている場合に、パスの末尾に 「.index」 などの文字を追加したいとしましょう。 その場合は次のようなフィルタを書けばよいです。
package info.vividcode.example; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.PreMatching; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; /** * リクエスト URI のパスがスラッシュで終わっている場合に、パスの末尾に 「.index」 を追加するフィルタ。 * 末尾のスラッシュの有無に応じて、ディスパッチされるリソースを別にするため。 */ @Provider @PreMatching public class IndexPathAddingFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { UriInfo uriInfo = requestContext.getUriInfo(); if (uriInfo.getPath(false).endsWith("/")) { UriBuilder uriBuilder = UriBuilder.fromUri(uriInfo.getRequestUri()); uriBuilder.path(".index"); requestContext.setRequestUri(uriBuilder.build()); } } }
JAX-RS では、パスの末尾にスラッシュがあってもなくても同じリソースにマッチするので、パスの末尾にスラッシュがあるかどうかでマッチするリソースを変えたい場合には上のようにするのも 1 つの手だと思います。
JAX-RS アプリケーションの 404 Not Found のカスタマイズ (リソースが見つからない場合)
JAX-RS アプリケーションでリソースが見つからない場合に表示される 404 Not Found のレスポンスの内容を変更したい場合にどうすればいいか、という話。
リソースが見つからない場合: NotFoundException
が投げられる
まずは、そもそもの話として、リソースが見つからなかった場合に内部的にどういう処理が行われているのか見てみます。
JAX-RS 2.0 のドキュメントを見ると、3.7.2 節 「Request Matching」 において、リソースクラスやリソースメソッドの選択について書かれています。 そこには、リクエストにマッチするリソースクラスがなかった場合の処理として、次のように書かれていました。
(d) If E is empty then no matching resource can be found, the algorithm terminates and an implementation MUST generate a
NotFoundException (404 status) and no entity
マッチするリソースクラスが存在しない場合、NotFoundException
が投げられるようです。 マッチするリソースメソッドがなかった場合も、同様に NotFoundException
が投げられると書かれています。
例外をレスポンスにマッピングする: ExceptionMappter<T>
さて、内部的には例外が発生していることがわかりましたので、その例外をうまく扱いたいところです。
JAX-RS には、例外をレスポンスにマッピングする Exception Mapping Provider という仕組みがあります。 JAX-RS 2.0 のドキュメントの 4.4 節 「Exception Mapping Providers」 に次のように書かれています。
Exception mapping providers map a checked or runtime exception to an instance of
Response. An exception mapping provider implements theExceptionMapper<T>
interface and may be annotated with@Provider
for automatic discovery. When choosing an exception mapping provider to map an exception, an implementation MUST use the provider whose generic type is the nearest superclass of the exception
NotFoundException
を適当なレスポンスにマッピングするための Exception Mappging Provider を書くことで、リソースが見つからない場合の 404 Not Found をカスタマイズできます。 (もちろん、リソースが見つからない場合のエラー以外にも適用できます。)
サンプルコード
カスタマイズ前
以下のように、JAX-RS 実装として Jersey を使用し、Grizzly 上で JAX-RS アプリケーションを動かしているとします。
// 必要な import 文 import java.net.URI; import javax.ws.rs.core.UriBuilder; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.server.ResourceConfig; // 処理 URI baseUri = UriBuilder.fromUri("http://localhost/").port(10082).build(); ResourceConfig config = new ResourceConfig(); HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri, config);
上のコードでは、リソースクラスを 1 個も登録していないので、ブラウザで http://localhost:10082/ にアクセスしても 404 Not Found が返ってきます。 (ページ自体は真っ白。)
カスタマイズ後
以下のような Exception Mapping Provider を書いてみます。 単に 「404 Not Found!!!」 という文字列を表示するだけのレスポンスです。
import javax.ws.rs.NotFoundException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @Provider public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> { @Override public Response toResponse(NotFoundException exception) { return Response.status(Status.NOT_FOUND).entity("404 Not Found!!!").build(); } }
そして、以下のように ResourceConfig
に登録します。
URI baseUri = UriBuilder.fromUri("http://localhost/").port(10082).build(); ResourceConfig config = new ResourceConfig(); config.register(NotFoundExceptionMapper.class); HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri, config);
これで、リソースが見つからなかった場合にカスタマイズされた 「404 Not Found!!!」 という文字列が返されるようになります。