Androidのカレンダー関連のソースを読んで。
また久しぶりの書くけど。
何で書くかって、Android2.2のカレンダー関連のソースコードを読んでいたら、androidのクラスには、色々便利そうなクラスがあることに気がついたから。忘れないうちに。
読んだソースは、主にここと
https://github.com/OESF/OHA-Android-2.2_r1.1
ここ
http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2.1_r1/
実際に使ってはいないが、ソースコードを読んだ感じから。
- android.widget.ViewSwitcher
- これと同じ機能をもっているViewFlipperをつかっているけど、こっちでも良さそう。基本的に二つのViewしか保持しないみたいだけど、カレンダーとかって、前月とか次月とか無制限につなげる場合は、スライドする時に次のViewを生成するからね。
- android.database.ContentObserver
- ContentResolverにregisterContentObserver()を使って登録するクラス。名前のとおり、Observerパターンの実装でしょう。ContentResolverで特定のURIを受けたときに、特定の処理を実行するように登録できる。
- android.content.AsyncQueryHandler
- これも名前の通りのクラスでしょう。非同期でqueryを実行し、その検索結果を処理するためのクラス。
なんか、大体人が思いつきそうなクラスは、準備されているよね…
NHKの集金が来た
NHKの集金の人が来たよ。
なかなか来ないからおかしいなー?って思っていたんだけど。
まあ、毎週「将棋の時間」とか見てるんで、払ってもいいかなって思っている。
それと、たまに面白い番組やっているし。払うから面白い番組作ってね!
でも、ビックリしたのが、集金のおじいちゃんが持ってた端末。
手書きの文字を認識してしてたぞ!すげえ!
クレジットの決済をその場でやりやがった!すげえ!
セキュリティとかメッチャ心配だったけど。
でも、やってみると便利だ。
Androidとか流行る前から、ああいうのはあるんだよね。
水道、電話、電気、ガスと、普段使用している公共料金とか、
全部ああいう形で引き落としを簡単にできたらいいのに。
あ、あと交通違反の罰金もあんな感じで、どうよ?
ImageViewのLayoutParamsって…
Androidのお話で。
いやー、まいったねー。
ImageView iv = (ImageView) findViewById(R.id.image_a);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
iv.setLayoutParams(lp);
って書いたら、こんなエラーが出やがんの。
07-18 14:30:47.876: ERROR/AndroidRuntime(1504): Uncaught handler: thread main exiting due to uncaught exception
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): java.lang.ClassCastException: android.view.ViewGroup$LayoutParams
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:585)
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): at android.widget.LinearLayout.onMeasure(LinearLayout.java:280)
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): at android.view.View.measure(View.java:7964)
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
07-18 14:30:47.886: ERROR/AndroidRuntime(1504): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:888)
で、これは何が原因かっていうと。
ImageView iv = (ImageView) findViewById(R.id.image_a);
ここ→LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
iv.setLayoutParams(lp);
これは
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
とするべきところなんだねー。クラスが違うからClassCastExceptionになっているんだねー。APIにも"setLayoutParams()"は、Viewクラスから継承したメソッドで、引数はViewGroup.LayoutParamsって書いてあるけど、実際は違っているようですねー。きっとLayoutParamsのインスタンスから何か値を取得するクラス毎に用意する必要がありそうですね。
別にいいじゃんねー。同じ"LayoutParams"なんだし…。なんでわざわざ別々に…。
androidのちょっとした開発時のトラブルについて
hibernateのN+1問題について
hibernateを業務で使うことになりました。
やっほう!!
なんて思っていたら、早速N+1問題にぶつかった。
テーブルを結合してとってきて欲しいので、リレーションをアノテーションで記述してみたよ。
でも、流れているSQLは、一テーブル毎に検索するSQLだった。一生懸命、親レコード一つに付き、子レコードを検索するSQLを発行していたよ。
じゃあってんで、fetchを追加したら、検索結果の件数が子レコードの総数になったよ。
そうじゃないんだ。欲しいのは親レコード-子レコードの結果なんだ。だから検索結果の件数として欲しいのは、親レコードの件数なんだ。親レコードから処理を始めたいんだ。
mappingの戦略(?)といったものが指定できるんであれば、そうしたい。
コードが短いのは結果でしょ?
ソースコードを短くすることに血道をあげる人がいますが、私は短くすることはそれほど重要視していません。
ソースコードが短い=テストが少なくて済む
確かにその通り。でも、それを目的としていいの?
本当に満たすべき要件は満たしているの?
短くすることで、かえって分かりにくくなっていない?
一行の中で、メソッドを何度も呼び出して、それでソースコードを短くして
「これでスッキリしました」
っていってない?
スッキリしたのはお前だけだって。
必要なら行数はかけるべきだし、短くしすぎて分かりにくくなるなら、行を分けるべきだ。後から読んで分からなくなるなら、そんなコードは書くべきではない。
ソースコードが少ないのは、リファクタリングを繰り返し、ソースコードを洗練させた結果であるべきだと思う。
「こんなことは分かっている」と言う人は多いでしょう。でも「短いことはいいことだ」と結論だけを聞いてしまうと、結果に過ぎないことを目的と勘違いする人がいそうでね。