RSS

来年向け:MessagePack

通信用のライブラリとして最も気になっているのが、MessagePack

Google のProtocolBuffersと比べても4倍も高速という辺りが非常に興味深い。

シリアライズの負荷も小さく、サイズも小さいという理想的なライブラリに見えます。
ハード性能、ネットワーク帯域がどんどん大きくなるから
そういったものは必要ないじゃないか、という気もしますが、全然違う。

アプリケーションが通信を行う量の方が其れ以上の速度で増えていますし、
パブリッククラウド上に乗せる場合は計算量、ネットワーク流量が
まんま使用料として跳ね返ってくるわけですし。

なので、今でもこういうのは重要。
てなわけで、調べてみよう、っと。

来年向け:Sonar

そろそろ今年も終わり、ということで、来年に調べると面白そうな技術要素を
列挙していく方針で。

今回はSonar。(InfoQ


何かというと、ソースコード品質管理ツール。

リポジトリに登録されたソースコードに対して解析を行い、
結果をレポート形式で出力するツールです。
ソースコードの量やら、コメント率やら、ソースコードの複雑度やら。

これだけだと他にもあるんですけど、面白そうなのは「アーキテクチャルール」。

===
開発者は、異なったパッケージにあるクラス間での参照を認めないパターンベースのルールを
定義することができる。
パターンの例には、*.dao.* クラスから*.web.*へのアクセスを禁止したり、
どのクラスからも java.util.Vector, java.util.Hashtable や java.util.Enumeration へのアクセスを
禁止するものが含まれている。
ソースコードがアーキテクチャ制約のセットに忠実に守れば、
プロジェクトは、アーキテクチャ モデルを遵守することになる。
このルールを使うには、Javaのバイトコード 分析が必要である

===

参照をルールとして定義して警告が出せるのは面白い。
これを利用すれば、下記みたいな解析が出来そう。

  1. DaoやJDBCドライバ系の参照を禁止することで、WebシステムでAction層からデータベースをレイヤーを無視してアクセスすることを検出
  2. 同一パッケージとプロジェクトのcommonパッケージにのみ参照を許すことで、後で他プロジェクトに機能を移行しやすくする
  3. スレッドやconcurrent系のパッケージに対する参照を禁止することで、開発者が独自方式でスレッドを起動することを検出

後は、Mavenのレポートも取り込める、となるとおそらく
CheckStyle、FindBugsといった
他の静的解析のツールの結果も統合して表示できるんだろうなぁ。

加えて、カスタムダッシュボードを作れる辺りも面白い。
この辺りは使うだけでなくて、OSSなので実際にソースコードを見てみるかなぁ。。。

Bloglines移行したんだけど、使い勝手がまるで違う。。。

最近妙に忙しいので一言のみ。

WebRSSリーダーサービス「Bloglines」がMarchant net という所に
移行したんですが、使い勝手が全然違ってきている。。。。

これだとGoogle RSS Readerの方がよほど使いやすい。
ということで移行先ではなく、Google RSS Readerに移る事を決心した今日この頃です。
ただ、Android携帯できちんと見れるのか、が微妙に不安。
まぁ、とりあえず試してみますか。。。。

【続】Android携帯のIPアドレス

この間の結果ですが、特に基地局をまたいでもIPアドレスは変わりませんでした。

普通に起動したときに基地局の更にバックグラウンドにある
存在からIPを割り振られている模様。

起動したときに表示される識別子っぽい
xxxx.mopera.netという値がIMPIだったり、IMPUを示しているのかな?
#IMPI/IMPUについてはこちら

ともあれ、これでServerman等も一度起動しておけば
終了するまでは固定アドレスでアクセス可能ということもわかりました。
当たり前と言えば当たり前な気もしますが、一つ何かわかった気はします。

Android携帯のIPアドレス

気になって調べてみたのが、Android携帯のIPアドレスって、
どうやって決まっているのかな?、ということ。

というか、Android携帯がどういう経路でネットワークを出ていっているのかな、
と書いた方が正確かも。

とりあえず何度か確認してわかったことは、下記の2点。
#但し、基地局エリアはおそらくまたいでいないので、
#同じ基地局エリアにいる、という前提で。
1.IPアドレスは端末を再起動すると変わる。
2.XXXX.mopera.netを経由してアクセスしているらしい。。。

基地局をまたいだ時点でIPが変わるかどうかは、
これから電車で移動して基地局またぐので、それで確認してきます。。。

Android Layout Editorでエラー起きて表示されない!

サンプルアプリの内容が大体出来て来たので、
今度はレイアウト調整、ということでAndroid Layout Editorで画面を作成。

。。。なんですが、いまいち下記の問題があって使いにくい。
1.android:backgroundの指定次第ではWYSIWYGビューで例外発生
2.画像のサイズがWYSIWYGビューでは調整されない

1.android:backgroundの指定次第ではWYSIWYGビューで例外発生

android:backgroundにdrowable/XXXを指定してxmlファイルを読み込ませると
何故かWYSIWYGビューでUnsupportedOperationException: nullが発生してしまいます。
で、全くWYSIWYGビューが表示されないという状態に。

デフォルトのボタンだといまいち味気ないので、
デザインを変えようとすると毎回発生するという厄介な状態です。


2.画像のサイズがWYSIWYGビューでは調整されない

ImageViewに、ImageViewよりもサイズが大きい画像をandroid:srcに指定すると、
WYSIWYGビュー上では画像がフルサイズで表示されてしまいます。
なので、下のように画像が切れてしまう。
なんですが、実際にエミュレータや実機で表示してみると画像のサイズが
ImageViewのサイズに補正されて、切れない。

なんかこの辺りも解消する方法がありそうなんですが。。。
とはいえ、別にアプリが動かないわけではないから解消は気長に。

■切れる前


■切れた後

画面の縦横を切り替えてもonDestroy等が呼ばれない方法

昨日に引き続き。

あるんじゃないか、と思って調べていた
『画面の縦横を切り替えてもonDestroyが呼ばれない方法』ですが、
案の定ありました。

記述としては、AndroidManifest.xmlに下記のように記述すればいいようです。

===
        <activity android:name=".AlarmTimerActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden"> ★この行★
===

上記の記述をすることによって、
orientation(向き切替)、keyboardHidden(キーボード収納)をした際に
Activityが再生成(onDestroyとか)がされなくなるようです。

代わりに「onConfigurationChanged」というメソッドが呼ばれるので、
必要ならば上記のメソッドに処理を入れ込めばいいそうな。

尚、本来はkeyboardHidden(キーボード収納)を設定する必要が無いような
気がするのですが、keyboardHiddenを外してみると、
一部のフィールドが初期化されてしまって切替時にNullPointerExceptionが発生するため、
設定している状態です。

ちなみに詳細はAndroid:Activityのページにありました。

画面の縦横を切り替えるとonDestroyが呼ばれる?

テストアプリの動作確認を行っていたときにわかったのですが、
Androidって、画面の向きを変えるときに何故かonDestroyが呼ばれてしまうようです。
実際、ブレークポイントをはったらきっちり引っ掛かりました。

呼ばれるメソッドの流れは下記の模様。
。。。普通に終了処理になっているようです。

-onPause()→onStop()→onDestroy() →onCreate()→onStart()→onResume()

かつ、onDestroy→onCreateが呼ばれる際にActivityクラスも再生成されるため、
インスタンス変数に画面方向切替時に持たせたい情報を持たせておいても、
当然クリアされてしまう。
実際、ActivityのObjectIDもonDestroyのタイミングと
onCreateのタイミングでは変わっていました。

ただ、どうやらクラスはロードされっぱなしになるため、
クラス変数にフラグを持たせればどうやら保持される模様。

なので、タイマーの動作を引き継ぐのに必要な変数だけはクラス変数化して、
onCreate時にクラス変数の状態で処理を切り替えれば対応可能。。。なのかな?

ただ、それでもonDestroyが呼ばれてしまう以上Serviceクラスとかも
まるまる再生成されてしまいます。
さすがにonDestroyが呼ばれた際にサービス等をunbindしないわけにはいかないので。

何か効率が悪い気がするんですが。。。。はてさて。

Androidエミュレータにマーケットのアプリケーションをインストールする方法【詳細】

前回投稿した、Androidエミュレータにマーケットのアプリケーションを
インストールする方法の詳細記述です。

1.Android携帯にインストールされているapkファイルをバックアップする

Android携帯で、バックアップ系のソフトを使ってインストールしているapkファイルを
ファイルとしてバックアップします。

例として、今回私が使ったのは『AppMonster』というアプリケーション。
Androidマーケットで『AppMonster』として入力すればすぐ見つかるはず。

起動するとインストールしてあるアプリケーションの一覧からバックアップ対象の
アプリケーションが選択できます。

選択すると、/sdcard/appmanager というディレクトリ配下にファイルが出力されます。
インストールしてあるアプリのapkファイルが
出力されていることを確認したら、次の手順へ。


2.PC⇔Android携帯で接続し、apkファイルをPCに移す

Android携帯をUSB経由でPCに接続し、apkファイルを取得します。
1で出力された「/sdcard/appmanager」のディレクトリを確認すると、あります。

それを、ローカルに配置する。こんな風に。




















3.Androidエミュレータのコマンドを使用して、エミュレータにapkファイルをインストールする。

2まででapkファイルをローカルに置くことが出来ましたので、
後はインストールを行います。
ただ、その前にAndroidエミュレータを起動しておきます。
起動していないと、こんな感じにデバイスないよ、と怒られてしまいますので。


















てなわけで、Androidエミュレータを起動。
ちなみに、インストール前はこんな状況です。



エミュレータが起動したのを確認したら、「adb install 【APKファイル】」
という形式のコマンドを実行します。
すると、インストールされます。
尚、この際複数のAndroidエミュレータを起動していたり、
実機のAndroid携帯を接続していたりすると、
どれか一つにだけインストールされますので注意。
















Success、と表示されたらインストール成功。
成功すると、いつの間にやらアプリ一覧に追加されています。
特に画面の切り替えとかはしていませんが、いつの間にやら。
この辺りのリアルタイムさはさすがだなぁ。



これでインストール方法は以上。
インストールしたアプリケーションから通信も出来るようなので、
Android携帯を複数用意して試したい、という場合は有効かも。

Androidエミュレータにマーケットのアプリケーションをインストールする方法

AndroidエミュレータからではAndroidマーケットにアクセスすることはできませんが、
アプリケーションをインストールする方法は無いのかな。。。と考えていましたが、
とりあえず見つかりました。

手順は下記の通り。
1.Android携帯にインストールされているapkファイルをバックアップする。
2.PC⇔Android携帯で接続し、apkファイルをPCに移す。
3.Androidエミュレータのコマンドを使用して、エミュレータにapkファイルをインストールする。

・・・なんですが、時間なので、続きは明日に。

Androidのスレッド一覧を確認してみました

昨日のHandlerの存在を受けて、
Androidでのアプリ実行中のブレークに引っ掛かるスレッドと、
その時点でのスレッド一覧を確認してみました。

とりあえず、確認したのは下記の○パターン。
1.onCreateでActivityを初期化している時
2.画面上のボタンにListenerを設定して、Listenerから処理を実行している時
3.TimerからHandlerを経由してTaskを実行している時
4.TimerからTask実行時、Handlerに処理を委譲する前の時

結果としては、1、2、3はmainスレッドでの実行。
4だけ自前で作ったスレッド上での実行となっていました。

なーるほど。確かにmainに委譲されて実行されている。
で、Lisnenerから呼び出される処理についても、
待ち受け処理からHandler経由でmainに委譲されているのかな。

この辺りも調べてみると面白そうではありました。とまぁ、今日はここまで。

確認結果詳細は続きに。

タイマーが動かなかった理由、判明

昨日困っていた、タイマーが動かなかった件ですが、
実はタイマーが動かなかったのではなく、
Handlerを経由せずにGUIに対してアクセスするタスクを実行していたからでした。
#具体的にGUIアクセスしている個所は★参照

Handlerってなんじゃらほい、と思って調べてみると、
throw Life:AndroidのHandlerとは何か?に、解説が。

実は、AndroidのGUIはシングルスレッドで動いており、
画面に対してアクセスが可能なのはメインスレッドだけ、とのこと。
で、メインスレッド以外がアクセスすると例外(CalledFromWrongThreadException)吐くそうな。
今回の場合、CatchしているのがRemoteExceptionだけなので、
当然runから例外が飛び出してジエンド、という。

なので、タイマーからGUIを操作したい場合は
何かしらの形でメインスレッドに処理を委譲する必要があるわけでして。
その委譲を行ってくれるのがHandlerだそうな。
なるほどねぇ。。。GUIといっても、Swingとはこの辺りは全然違う。

ただ、気になるのはボタンにイベント定義してリスナ仕込んだ場合は
特にHandlerにpostしなくてもGUIに対する操作が動くんですよね。
てことは、タイマーから叩くのは別スレッドだけど、リスナから呼び出される場合は
メインスレッドを経由して実行されるということなのかな?
ただ、リスナって待ち受けスレッド用意するようなものだからなぁ。。。はてさて。

一度Androidのスレッドモデルについて調べてみる必要がありそうだなぁ。

とりあえず、明日デバッグかけて確認してみます。

===
            TimerTask timerTask = new TimerTask() {
                public void run()
                {
                    try
                    {
                        Toast toast = Toast.makeText(getApplicationContext(), "Count Start", ★ここ★
                                Toast.LENGTH_SHORT);
                        toast.show();
                        targerCallback.updateTimerText();
                    }
                    catch (RemoteException e)
                    {
                        e.printStackTrace();
                        Toast toast = Toast.makeText(getApplicationContext(), "Count Failed",
                                Toast.LENGTH_SHORT);
                        toast.show();
                    }
                }
            };
===