cockscomblog?

cockscomb on hatena blog

Androidアプリ開発を始めるときに読む本

今年はついにAndroidアプリを作りました。Androidアプリを開発するに当たって、Java言語にもAndroidプラットフォームにも明るくなかったので、勉強しようと本を読みました。いろいろ読みましたが、そのうち特によかったものを紹介します。

Java言語

Effective Java

Javaをちゃんと書けるようにしようと思って読みました。JavaのSerializableやClonableの挙動について知識を得られたし、Javaの言語上の特性を意識した設計について一定の視座を得られたように思います。読まずにJavaを書けていたとは思えないので、大変有意義でした。『並行性』の章などはまた再読したいと思います。

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

Android

プロの力が身につくAndroidプログラミングの教科書

ActivityやServiceにContentProvider、レイアウト、テストなど、一通り書いてあります。おおよそ網羅的で、どのような要素があるのかを最初に把握できます。これはアプリの設計においてなるべく正しい手段を選択するために必要なことだと思います。とにかく一通り書いてあるというのがとても良くて、なかなか他にはありませんでした。Androidアプリの開発を学ぶときに最初に手に取るべきは本書だと思います。

プロの力が身につく Androidプログラミングの教科書

プロの力が身につく Androidプログラミングの教科書

Master of Fragment

Fragmentのライフサイクルや復元、Support LibraryのFragmentについて、あるいはアニメーションについてなど、Fragmentについて学ぶべきほとんどのことが書いてあります。AndroidではFragmentでけっこうハマると思うので、Fragmentを活用したいならこれを読むとよいでしょう。

達人出版会でベータ版が買えるという状態ですが、いろいろなフォーマットに対応しているので不便はないと思います。

Master of Fragment (Android Professional Developerシリーズ)
あんざいゆき, わかめまさひろ
達人出版会
発行日: 2014-02-14
対応フォーマット: PDF, EPUB

Android Security 安全なアプリケーションを作成するために

AndroidiOSより自由度が高く、アプリ間の連携の仕組みもリッチですが、その副作用としてセキュアじゃないアプリを簡単に作れてしまいます。本書はAndroidの基本的なセキュリティの仕組みから解説されていて、とても役立ちます。Androidアプリを作るときには必ず理解しておきたい内容が書かれています。

Android Security  安全なアプリケーションを作成するために

Android Security  安全なアプリケーションを作成するために

Androidアプリ開発のセキュリティについては『Androidアプリのセキュア設計・セキュアコーディングガイド』も役に立ちます。

まとめ

Androidアプリ開発に入門するには、大体上記の4冊くらいを読めばよいと思います。あとはGoogleのドキュメントを眺めるとか、APIのdiffを全部見るとか、最新のイケてるライブラリを調べるとかするのがよいでしょう。技術の進歩が早い分野ですから、絶えず知識をアップデートしていく必要があります。

これから年末年始で、退屈凌ぎにAndroidアプリ開発を学ぼうという皆さんのお役に立てたらと思います。

WatchKitアーキテクチャ概論

来年初めにリリースされるというApple WatchSDKがプレリリースされた。Appleはこれを WatchKit と呼ぶ。Apple Watchで動作するWatchKitアプリは、いったいどのようなアーキテクチャにより駆動されるのか。この興味深い仕組みについて考察する。

WatchKit - Apple Developer

ふたつの予想

Appleウェアラブルデバイスを開発しているという噂が流れていた頃、そのアプリケーションのアーキテクチャについて異なる二つの予想をしていた。

一つは、ウェアラブル端末本体で動作する通常のアプリを作るというパターン。これはAndroid Wearが採用しており、Androidのアプリを作るのとほとんど同じようにウェアラブル端末で動作するアプリを作ることができる。これが採用されると、UIKitの多くのコンポーネントが利用できることになり、柔軟なアプリを作成できる。その反面でウェアラブル端末の少ないバッテリーは大きく消費される恐れがあるし、比較的非力なSoCに最適化する必要がある。加えて、ウェアラブル端末には通常インターネットに接続する機能はなく、コンパニオンとなるスマートフォンから借用することになるが、これを実装するのは面倒な作業になる。

もう一つは、コンパニオンとなるスマートフォンの側にアプリの機能を実装し、その画面をウェアラブル端末に表示するというパターンである。すなわちウェアラブル端末をセカンドスクリーンとして用いることになる。結果としてウェアラブル端末のハードウェア上の機能に束縛されることなくアプリを作ることができる。これはApple TVを利用するAirPlayや、車載端末であるCarPlayアーキテクチャに近いものであろう。ただし、ウェアラブル端末とスマートフォンは現行の技術ではBluetooth Low Energyで接続されることが予想され、画面を逐一転送できるだけの通信速度は出ないだろうと思われる。

これらの二つの予想は、それぞれに利点や問題を持っている。ただAppleの最近の技術的なトレンドを考慮すると、後者の方に分があるように思われた。

WatchKit

プレリリースされたWatchKit SDKのページを見ると以下のように記載されている。

WatchKit apps have two parts: A WatchKit extension that runs on iPhone and a set of user interface resources that are installed on Apple Watch. When your app is launched on Apple Watch, the WatchKit extension on iPhone runs in the background to update the user interface and respond to user interactions.

すなわち、ウェアラブル端末であるApple Watchには、Storyboardやリソースファイルだけをインストールし、コンパニオンとなるスマートフォンであるiPhoneの側でApp Extensionとしてプログラムが動作する。Apple Watchのユーザーインターフェイスが操作されればそれはiPhoneのExtensionに伝わり、iPhoneのExtensionからApple Watchのユーザーインターフェイスを更新する。

これは最初の二つの予想のちょうど中間的なアーキテクチャと言える。アプリはiPhoneの側にその多くを置いて、ユーザーインターフェイスApple Watchの側で動作させる。結果として多くの問題が解決され、アプリはiPhoneの潤沢なリソースや機能を利用できるし、BLEで画面を送信する必要もない。

注意すべきは、Apple WatchとiPhoneの間のやりとりに遅延が生じることである。例えばユーザーインターフェイスが操作されたときのインタラクションはApple Watchの側で素早く表示しつつ、少し遅れてiPhoneでアクションが起きる、ということになる。このことで、iPhoneのExtensionからApple WatchのViewの様子を取得することができないようになっている。iPhoneの側で、Apple Watchのユーザーインターフェイスに行った操作を記憶しておく必要がある。

また画像リソースはなるべくApple Watchのリソースに含めておくべきである。それができない動的に生成または取得される画像は、キャッシュとしてApple Watchの側へ登録しておくことで、再表示するときのコストを大きく下げられる。

この他にも制限は多く、例えばカスタマイズされた独自のユーザーインターフェイス要素は、Apple Watchで利用できない。WatchKitで事前に用意されたユーザーインターフェイス要素だけを用いてデザインする必要がある。

総論

Apple WatchとWatchKitのSDKは、ウェアラブル端末に注意深く最適化されたものであることが読み取れる。WatchKitのアーキテクチャによって、優れたユーザーエクスペリエンスが得られるだろう。

またこれはApple Watchに限らず、その他のiOS関連機器にも有効なアーキテクチャであると考えられる。CarPlayApple TVのほか、将来登場するかもしれない新たな端末にも応用可能である。

いずれにせよWatchKitのこのアーキテクチャは、AppleiOSOS Xで長年開発してきた技術の結実である。

ところでWatchKitアプリに独自のユーザーインターフェイスを作ることは未来永劫できないのだろうか。恐らく答えはXcodeにある。Xcode 6から、Interface Builderに独自のViewを表示できるようになった。内部的には独自のViewをXcodeとは別のプロセスで動作させ、レンダリングさせているように見える。WatchKitアプリでも、Apple Watch側でカスタマイズしたViewだけを動作させることは技術的に可能になると予想できる。将来のWatchKitでそのような機能が搭載されるかもしれない。


※ 以上の内容はAppleによって公開された情報を元に書かれています。

「記憶に残る風景」 #地元発見伝

「記憶に残る風景」 #地元発見伝

https://www.google.com/maps/preview?q=43.086833%2C141.317335

札幌市, 北海道

小学校。

https://www.google.com/maps/preview?q=43.080485%2C141.315322

札幌市, 北海道

中学校。

https://www.google.com/maps/preview?q=43.090155%2C141.333653

札幌市, 北海道

高校。

https://www.google.com/maps/preview?q=43.07828%2C141.341148

Google Maps

大学。

地元の魅力を発見しよう!特別企画「地元発見伝

http://partner.hatena.ne.jp/jimoto/


その辺にたくさんうろついている人間たちには、それぞれの人生があって、それぞれの地元がある。僕は就職して京都のインターネットサービスの会社で働いているけど、地元は札幌。

地元にはいろいろあるけど、最近になってもよく学校の夢を見る。たいていは、宿題やってなくて困ったとか、試験勉強しないといけないけどやりたくなくて困ったとか、そういう夢を見る。その当時の同級生が出てきたり、なぜかいまの同僚が出てきたりする。けどたいてい、困っている。

仕事をし始めてよいことのひとつは、宿題や試験に追われることがなくなったことで、家に帰ればのんびりできる。もちろん勉強したりもするけど、それは趣味のようなものだから気にならない。僕は不真面目な人間に生まれたようで、宿題とか試験勉強ができない質のようである。

ところで働き出して2年くらいだけど、その間にまだ1回しか帰省していなかった。ので明日、ちょっと遅い夏休みを取って帰省します。

お土産買ったので楽しみにしていてください。

Android Studio便利テク #3 — メソッドをグルーピングする

Javaでクラスの実装を進めていくと、あるメソッドが継承元クラスのメソッドをオーバーライドしているのか、あるいは何らかのinterfaceの実装なのか、だんだん見分けがつかなくなります。一定の規則でメソッドを並べたり様々な工夫があることと思います。


Xcodepragma mark

#pragma mark - UITableViewDelegate

iOSアプリ開発に慣れていれば、上記のような#pragma markを残しておく習慣があることでしょう。ちなみにSwiftでは以下のようになります。

// MARK: - UITableViewDelegate

region

Android Studioにはpragma markとは少し違いますが、regionというコメントの書き方があります。

    //region GoogleApiClient.ConnectionCallbacks
    @Override
    public void onConnected(Bundle bundle) {
        connectLocationService();
    }

    @Override
    public void onConnectionSuspended(int i) {
        disconnectLocationService();
    }
    //endregion

上記のように//region//endregionの間に囲まれた範囲を、任意の名前で定義することができます。この例であれば、二つのメソッドGoogleApiClient.ConnectionCallbacksインターフェースの実装であることが明白です。

f:id:cockscomb:20140813230713p:plain
Surround Withで選択範囲を囲う

f:id:cockscomb:20140813230732p:plain
//regionコメントで囲まれている

またこのregionの範囲はフォールディングできます。

f:id:cockscomb:20140813230747p:plain
region部分がフォールディングされている

ちなみに//regionの書き方はVisual Studio風ですが、NetBeans<editor-fold desc="GoogleApiClient.ConnectionCallbacks">``</editor-fold>という書き方もできます。


本質的には、クラスにメソッドが増え過ぎて迷子になるようなら、役割が広すぎるクラスになってしまっているのかもしれません。そのような場合でもコメントなどによって適切なグルーピングが行われていれば、リファクタリングの助けになるでしょう。いずれにせよ、読みやすくコードを整理することはよい習慣です。

プロの力が身につく Androidプログラミングの教科書

プロの力が身につく Androidプログラミングの教科書

Android Studio便利テク #2 — デバッグ中にbyte[]の中身の文字列を読む

Androidアプリの開発では、デバッグ中にbyte[]型のバイト列を見ることがあります。ネットワーク通信の結果やファイルから読み出したデータなど様々ですが、たいていの場合は文字列です。本記事では、Android Studiobyte[]の内容を簡単に確かめる方法を紹介します。


例えばネットワーク通信のレスポンスとして、40Xのステータスコードと共に、ボディにエラーの内容を表すバイト列が含まれているとします。そのようなとき、エラーの内容を知るために

byte[] body = response.getBody();
Log.d(TAG, new String(body));

のようなコードを事前に仕掛けておいてログを眺めるのはいかにも効率が悪いですね。このようなプリントデバッグでは、目的の情報が得られるまでに何度も実行してみないといけないかもしれません。

ブレークポイントを置いてデバッガで止めてみるのは良いアイデアです。しかしデバッガでVariablesを見てみても、表示されるのはただのbyteの配列であり、お世辞にもわかりやすいとは言えません。

f:id:cockscomb:20140805193018p:plain
デバッガでVariablesを表示するとbyte[]が見える

Expression Evaluation

デバッグ中にExpression Evaluationボタンを押すと、Javaのコードを評価できるダイアログが表示されます。

f:id:cockscomb:20140805193052p:plain
Expression Evaluationでは任意のJavaのコードを評価でき、byte[]の中身を確かめられる

String.copyValueOf(new String(message).toCharArray())

ここで上記のコードを評価すると、byte[]型の値をStringオブジェクトに変換でき、内容が表示されます。

new String(message)のようにできそうに思いますが、手元のAndroid Studio 0.8.2ではなぜかうまく表示されませんでした。

Data Type Renderers

Debuggerの設定のData Type Renderersでは、byte[]型の値を表示するのに評価されるコードを設定することができます。

String.copyValueOf(new String(this).toCharArray())

f:id:cockscomb:20140805193124p:plain
Data Type Renderersbyte[]の表示に利用するコードを設定できる

このように設定しておくことで、Variablesにいつでも内容が表示されるようになります。

f:id:cockscomb:20140805193140p:plain
Data Type Renderersが設定されているとVariablesにその評価結果が表示される

Expression Evaluationを毎回実行する必要もなくなり、たいへん便利です。


今回紹介したのはIntelliJ IDEA由来のデバッグ機能です。便利な機能を利用することで、より効率的に開発することができます。

ここでお知らせですが、筆者の勤務先である株式会社はてなが、京都でAndroidの勉強会を開催します。

「京都 Android 勉強会」を8/23(土)に京都で開催します! #kyotoandroid - Hatena Developer Blog

筆者も発表を行いますので、皆さまぜひご参加ください。懇親会でお待ちしています。

Android Studio便利テク #1 — フィールド名にプリフィックスを付ける

Androidの一般的なコーディングスタイル*1によれば、フィールド名にいくつかの規則がある。このなかにprivatestaticじゃないフィールドはmから始まること、staticなフィールド名はsから始まること、という二つの決まりがある。

Android Studioでそのように書いていると、ゲッターやセッターをGenerateしたときなどにちょっと困ったことが起きる。

    private Object mField;

    public Object getField() {
        return mField;
    }

    public void setField(Object field) {
        mField = field;
    }

本来は上記のようなメソッドが生成されてほしい。しかしデフォルトでは以下のようになる。

    private Object mField;

    public Object getmField() {
        return mField;
    }

    public void setmField(Object mField) {
        this.mField = mField;
    }

mの部分までメソッド名に入ってしまい、getmField()のようなアクセッサが生成されている。これを手でチマチマと修正してはいないだろうか。

Android Studioでは、PreferencesからCode StyleJavaを開いて、Code GenerationタブのNamingルールを変更することでこれを解決できる。

f:id:cockscomb:20140803221407p:plain
NamingルールにName prefix:を設定する

プロジェクト単位ではなくデフォルト値を変えたければFileメニューから辿るとよい。

f:id:cockscomb:20140803221353p:plain
FileメニューからOther SettingsDefault Settings…と辿る

またこれらの設定はRefactor ThisからField…を選択したときのデフォルトの名前にも適用される。

一般的に便利なので必ず設定しよう。


下記の書籍にはこれらの情報は記載されておりませんが単に役に立ちます。

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

モバイルアプリのObserverパターン

ReactiveCocoa勉強会関西にてObserverパターンについてお話ししましたので、以下にその内容をまとめます。


Observerパターンは、GoFの23のデザインパターンのうちの一つで、モデルが状態の変化をしビューに通知するパターンです。GUIアプリケーションの開発で多用されます。もちろんスマートフォンアプリの開発においても大変役に立つので、いくつかの例を挙げて見ていきます。

Objective-CのKey-Value Observing

static void * Context = &Context;


- (void)anything
{
    [object addObserver:self
             forKeyPath:NSStringFromSelector(@selector(property))
                options:NSKeyValueObservingOptionNew
                context:Context];
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (context == Context) {
        doSomething();
    }
}

上記は監視する側の例です。NSKeyValueObservingプロトコルaddObserver:forKeyPath:options:contextを呼び出し、変化があったときobserveValueForKeyPath:ofObject:change:context:が呼ばれるというものです。NSStringFromSelector()contextを利用するのは良い習慣です。

self.property = object;
NSMutableArray *arrayProxy =
    [array mutableArrayValueForKeyPath:
        NSStringFromSelector(@selector(property))];
[proxy addObject:object];

KVOの通知を発火させるためには、Key-Value Codingに準拠するようにプロパティへの代入を行うか、あるいはコレクションのKVOを発火させるためにmutableArrayValueForKeyPath:が返すプロキシオブジェクトを利用します。

このようにObjective-Cでは、KVOという仕組みによってObserverパターンを簡単に利用できるようになっています。

AndroidJavaのObserverパターン

AndroidにおけるObserverパターンの実現ためには、素朴にObserverパターンを実装するほか、java.beansパッケージのPropertyChangeSupportクラスを利用する方法があります。

public class Bean {
    private final PropertyChangeSupport mChanges;

    private String mName;


    public Bean() {
        mChanges = new PropertyChangeSupport(this);
    }


    public void addListener(PropertyChangeListener listener) {
        mChanges.addPropertyChangeListener(listener);
    }


    public void deleteListener(PropertyChangeListener listener) {
        mChanges.removePropertyChangeListener(listener);
    }


    public String getName() { return mName; }


    public void setName(String name) {
        String oldName = mName;
        mName = name;
        mChanges.firePropertyChange("name", oldName, mName);
    }

}

PropertyChangeSupportインスタンスを保持し、PropertyChangeListenerインターフェースのオブジェクトを受け付けます。そして監視させたいフィールドの変更があったとき、firePropertyChange()を呼び出すことで、PropertyChangeListenerPropertyChangeEventが送られます。

java.beansパッケージの中で、このPropertyChangeSupport関連の機能だけがAndroidにも存在しています。KVOと似たような形で利用できるかもしれません。

またjava.util.Observableを継承するという方法もありますが、あまり使い勝手が良くないかもしれません。

Swift

Swiftについてはどうでしょうか。SwiftからもNSObjectのKVOは利用できます。しかし純粋なSwiftのオブジェクトについては、これまでのKVOは利用できません。

Appleのドキュメント“Using Swift with Cocoa and Objective-C”の“Adopting Cocoa Design Patterns”を参照すると、今日現在で

Information forthcoming.

となっています。正式なリリースまでに何か明らかになるとよいのですが。

ここからは与太話ですが、もしSwiftにKVOライクな仕組みが導入されるとしたら、Objective-Cのようなランタイムで動的に何かするのではなく、コンパイルタイムで解決できるような仕掛けになるのではないでしょうか。そのほうがSwift的で、より安全かつ最適化しやすいようにも思います。

以上となりますが、今後もライフワークとしてObserverパターンについて考えていきたいと思います。