2014年7月11日金曜日

AndroidでのListenerとCallbackの違い

AndroidでのListenerとCallbackの違い

Androidの勉強を始めてしばらくするとListenerやCallbackが出てきますが、Androidでの両者の違いをどう定義しているのか少し引っかかったので調べてみました。

大意としてはコールバックの方が根幹になる名詞で、リスナはコールバックに含まれてしまう、つまりどっちも同じでしょ、と言われればそうとも言えますが、個人的には「リスナ」と言われるとUIイベントをイメージし、「コールバック」と言われると内部処理をイメージしながら聞いています。

一般的な定義

  • Callback
    呼び出し先の処理が終了した時点で(呼び出し元から指定された)関数が実行される事。
    その為、呼び出し元から呼び出し先関数を実行する再に関数ポインタを渡しておく。
    呼び出し先で何らかのイベントが発生した時にそれを検知し通知する為の仕組み。
  • Listener
    概要はコールバックと同じ。言語やフレームワークにより定義はマチマチ。
    ちなみにJavaには関数ポインタが存在しないので、コールバックの実現にオブジェクトを使用している為か「リスナ」と表現される事が多い。
個人的にはUIイベント系がリスナ(イベントリスナ) 、UIイベント以外がコールバック、という感じで使い分けるものかなぁと漠然と考えていました。

Androidで気になったところ

しっくり版

Androidで最初の方に出会うのはイベントリスナだと思います。
Button button = (Button)findViewById(R.id.button); 
button.setOnClickListener = (new View.OnClickListener(){
    ...
OnClickListenerインタフェースです。

クリックイベントを取得する = UIイベント

なのでListenerという名前で実装されているのがしっくりきます。

あれれ版

同じく最初の方に出会うこれ。
public boolean onKeyDown(int keyCode, KeyEvent event){
    ...
KeyEvent.Callback インタフェースで宣言されている onKeyDown() メソッドです。KeyEvent.Callback インタフェースはActivityやViewが実装してくれているのでそれらの内部で上記のようにいきなりオーバーライドして使用する事ができます。
でもイベントリスナ(= UIイベント)なのにインタフェース名が Callback …解せない…

そう言えば

SurfaceHolder.Callback というのもありました。
Surfaceの位置やサイズが変更された時に surfaceChanged(), Surfaceが作成/破棄された時に surfaceCreated(), surfaceDestroyed() が呼び出されます。
これは…
UIイベントはUIイベントなんだけど、通常ユーザ発じゃないUIイベント、という考えでリスナではなくコールバックとして実装されている、と考えれば納得…。

リファレンスを確認

上に記載したインタフェースに関してリファレンスを読んでみましたが、、、定義がない。
で、APIガイドで見つけました。
Event Listeners
An event listener is an interface in the View class that contains a single callback method. These methods will be called by the Android framework when the View to which the listener has been registered is triggered by user interaction with the item in the UI.
イベントリスナはViewクラスのインタフェースで、1つのコールバックメソッドを含みます。これらのコールバックはリスナが登録されているViewの時UI中アイテムへのユーザ操作がトリガになりAndroidフレームワークから呼ばれます。
イベントリスナの定義として、Androidフレームワークから呼ばれるのはリスナ&コールバック共に存在するので置いておくとして、以下の2点は使えそうです。
  • Viewクラスのインタフェース
  • 1つのコールバックメソッドを含む
他リスナで色々調べると、上記2点の定義に当てはまらない(Viewクラスのインタフェースではない or 複数のコールバックメソッドが含まれる)のに xxx.Listener として定義されているインタフェースが出てくる事やイベントリスナの命名規則に当てはまらない(リスナインタフェースがOnXxxListenerでなくListenerで定義されてたり)ことから、ユーザ操作から生まれるAndroidフレームワークからの通知でも、リスナとイベントリスナを分けて定義しているようです。
  • イベントリスナ
    • Viewクラスのインタフェースとして定義されている
  • リスナ
    • Viewクラス以外のインタフェースとして定義されている
まだAndroidはやり始めなので、今後意識して見ていればこの辺りの定義はもう少し詰められるかも知れないです。

まとめ

  • イベントリスナ
    • ユーザ操作により発生する通知
    • Viewクラスのインタフェース
    • 1インタフェースに1つのコールバックメソッド
    • 命名規則がある(ぽい)
    • インタフェース OnXxxListener
    • コールバックメソッド onXxx()
    • リスナ設定メソッド setOnXxxListener
  • リスナ
    • ユーザ操作により発生する通知
    • Viewクラスのインタフェースではない
    • 1インタフェースに1〜複数のコールバックメソッド
  • コールバック
    • 基本的には内部処理結果の通知

という感じでしょうか。

自分で作るとしたら、
  • UI系コントロールを拡張する時、根本部分ならイベントリスナ
  • UI系コントロールを拡張する時、下位コントロール限定ならリスナ
  • 内部処理ならコールバック  

として実装すると何となくAndroidに合う気がします。。

最後に

KeyEvent.Callbackに関してはなぜリスナでなくコールバックとして実装されているのかまだピンと来ていません。View系クラス以外でも使えるようにと考えたとしても、Listenerという名前で定義してくれた方がスッキリするんだけどな、と思うのは

・コールバックを内部処理で使う
・リスナをUIイベント系で使う

と習慣づいてしまっているからかも知れません。
コールバックの仕組みをデザインパターンに落としたものにObserverパターンというものがありますが、リスナ系にしてもコールバックにしても仕組み自体は同じものなので今回省いてます。

2014年7月4日金曜日

その9 - 「Javaプログラマ Silver SE7」

photo credit: Bobbi Newman via photopin cc



概要

以前紹介した「Java言語プログラミングレッスン 上/下」の二冊はJavaの大枠がかなり丁寧に記載されていると思いますが、今回紹介する書籍「Javaプログラマ Silver SE7」はその比ではありません。


やはり資格試験の参考書&問題集という位置づけなだけありかなり詳細な箇所まで記載されています。
この問題集をやる前にもっとふんわりしたJavaの本しか勉強してなかったら恐ろしい事になっていたかも…と思ってホッとした覚えがあります。
しかも、試しに問題をいくつかやってみると「あれ問題が分かりにくい…」とか「継承のポリモフィズムの問題だと思ったのにシグニチャの問題!?」というようなもひっかけ問題が多々あります。
しかしそれはしょうがないのです。
実際の試験もそうだからです。
この書籍は実際の試験問題の類似問題がかなりの数記載されています。繰り返しこの書籍で勉強する事で実際の試験問題の問題文や問題コード、解答文に慣れる事ができると思います。

この書籍で出せた正答率程度は実試験でも取得する事ができると思います。私の場合もこの書籍での正答率96〜98%で実試験95%、同僚も概ね同じような感じでした。
書籍での正答率 ≒ 実試験正答率
ぜひ繰り返し問題をこなしてみてください。

ポイント

最初に

まずは書籍の正誤表サイトの確認です。
せっかく勉強するのに間違いを覚えてしまってもしょうがないですから、勉強する前に上記サイトで内容を確認しましょう。

期間

私の場合は忘れっぽい&急ぎで資格を取得する必要があった、という2点からこの書籍を購入して10日で受験しました。
体力的にかなり辛かったです。

もちろん、すでにJavaを業務で使用するなりして精通されている場合は「試験問題に慣れる」事をメインにすれば短期間での受験が可能だと思います。
そうでない方で急ぐ理由が対外的なところにない方は、繰り返しこなした方がいいと思います。
あと試験に関してですが、オンラインでいつでも予約可能です。
登録が少し面倒なのと、試験予約ではかなり席が埋まっているので3日以上前には試験予約を済ませておいた方がいいと思います。
 

検証コードを書く

各ポイントでの検証コードなのでとても小さなものになると思いますが、その詳細部分が試験では問われます。
少しでも疑問に思ったらプチコードを書いてみてください。

意識するところ

実試験でもこの書籍をこなす上で同様のポイントに気を付けなければいけません。
  • 変数の宣言、初期化、初期値代入
  • オブジェクト指向関連
  • 例外(文法だけでなく例外クラスも)
  • 問題コードを素早く読んで理解する
「Java言語プログラミングレッスン」で学んだ基本をふまえ、それよりも深い部分まで問われたりします。
問題をこなすうちに問題文の癖のような部分には慣れるとおもいますので、基本部分を深めるためにもやはり検証コードを書くことは外せないと思います。
 

最後に

私はケアレスミスをしてしまうタイプなので元々100%は厳しいですが、この試験で100%とか本当に凄いと思います。
ですがJavaの勉強を始めた時からそこを意識して、基本をしっかり押さえ深く掘り下げ、コードを読み慣れれば達成できない事はないとも思います。
ぜひJavaの知識を深め100%目指してみてください。

2014年7月1日火曜日

その8 - 「Javaプログラミングレッスン 下」のまとめ




下巻まとめ

下巻も終わりJavaをひと通りこなしたところでまとめておきます。

期間

下巻は3週間くらいで書籍の通し、プラス数個のプログラム作成までこなしてしまいましょう。
もちろんプログラム自体が初めての方はもっと時間をかけるのもOKです。

理解

文法の暗記が少ないだけに、「こう書くとこう動く」という部分が増えてくると思います。
そこは上巻から引き続きコードを書いて動作をしっかり把握しておいてください。 

使いこなす

下巻は基本部分よりもそれを使用した部分(スレッド、ファイル) や広げた部分(コレクションなど)が多いので、上巻より最初に暗記する部分が少ないです。その分バリバリとプログラムを作成して「慣れる」から「使いこなす」にステップアップしたのが感じられると思います。
どんどん色々な種類のプログラムを作成してJavaでのプログラム作成に慣れていきましょう。

予告

次回はJavaの資格取得の参考書、JavaプログラマSilver SE7を紹介したいと思います。