iVDr〜Restated Versatile Dashboard Interface
GodzillaのConsult Scan Toolの開発が一段落したので次の懸案事項に移る。Nexus9の断捨離の為に、以前開発したAndroidソフト”Versatile Dashboard Interface”の移植を開始する。移植先はLenovo Tab4 8Plusとこれも余り使っていないTabletである。Since the development of the Godzilla’s Consult Scan Tool is concluded, I shall commence to transfer the Inhouse Android software “Versatile Dashboard Interface” developed for Nexus9 in past to another device. Nexu9 tablet is currently under the disposal process. The transferee is the Lenovo Tab4 8 Plus Tablet which I have not used much as well.
機種変更によるアプリ改造ポイントは以下
- アプリiVDsをInstallし立ち上げるが、GPSエラーで動かない。安普請のLenovoタブレットはケチって磁気センサーが導入されていない。その為、Nexus9で実装したGPSクラスはHandling Errorとなり利用できないのだ。特に必要な機能ではない故、単純に該当箇所をコメントOutする。
- アプリが画素数が異なる機種間の画像サイズ自動調整機能を盛り込んでいない為、画像が画面に的確に画像が表示されない。セミ自動調整機能を盛り込む事で対応する。
以上を盛込んだ改造は至って簡単と云いたい処だが、開発当時はEclipse IDEを使ったが、今やGoogle StandardになったAndroid Studioは使ったことがない。尤もAndroid アプリ開発は5年前故仕様を殆ど忘れているので、ある意味手っ取り早いと言える。最初は試行錯誤の連続だったが、徐々に記憶も蘇ってきて3週間掛けて再構築に漕ぎ着ける。
今回のアプリ開発で苦労した点を復習しておく。
過去の記事のエッセンス編と言った処だが、Android開発に於けるオブジェクト指向プログラミングの核となる概念でもある。俺が最も悩んだポイントは、UI(User Interface)はシングルスレッドしか対応しておらず、他のスレッドからUIの操作を行うことはできない点になるかな。
- Event Listenerの実装
デモ事例の”rotate Needle”、”dynamic Graph”、や”Tachometer”ではボタンクリックのイベント(View.OnClickListener)を利用してハンドルしているし、SensorManagerクラスではセンサー計測値のイベント変化(onSensorChanged)に対応する仕組みが事前に組込まれている。しかしながら、Bluetoothで受信したデータをリアルタイムに描画するには自前で仕組みを作成する必要がある。
通常Handlerを使用するが、既にBluetoothの重い処理をHandlerで行っているので、二重で使用するのは極力避けたい気持ち。Handlerの代わりに同一のInterfaceを実装したClass間で特定の機能を共有できるInterfaceを導入することにする。只、Interface Classは1個のファイルとして作成しないとエラータになるので留意の事。
具体的なコーディングの手順は、- InterfaceのClass宣言
Bluetoothで受信した計測値を引渡すClass - Interfaceを実装するClass登録
TachometerとDynamic Graph描画Classをinterfaceにimplementする
- InterfaceのClass宣言
- 非同期処理Handlerの実装
UIに於いて画像処理等のHeavyな負荷環境下では画面がフリーズする事がある。
具体的にはGPSの住所検索でフリーズに直面。実際こんな機能は必要ないんだが。
負荷を低減させる為の手段として別スレッドで分散処理を行う非同期処理を担うJava標準の手法であるThreadクラスを利用する。具体的な手順は、- 親のUIスレッドから子スレッドにプロセスを投げて処理をさせる。
- 子スレッドの処理が終了したら、結果を親元のUIスレッドに戻す。この際、子スレッドからUIスレッドに直接アクセスすると、Exception(エラー)が発生するので、同Exceptionの回避を図る為、Handlerクラスを導入する。Handlerとはメッセージを一時的に蓄積・順番待ちの状況に置き(in queue)、データを非同期に送信する(post)仕組みだ。
- Bluetoothでの受信が途切れる現象
多くの方々はBluetooth Chatをそのまま流用していると思うが、受信が途切れる現象の対策として施策を講じている。具体的には、- Bluetooth Handlerを司るバッファーの宣言箇所を移動させて、データーを読込む都度バッファーをクリアするコードに修正する。尤も、データ漏れがあっても支障がない前提だが。
- “Bluetooth Chat”では配列を1024と大きくとっているが、Arduinoの転送データ長は20バイト固定長故、配列の大きさを最小限の20バイトにおさえてスピードの向上を図っている。劇的な効果を確認。
- Memory leakの処理
当初、Android初期機種”Memopad”で開発を進めていた事もあってクラッシュが多発し、GC(Garbage Collection)なる見慣れぬ警告が発出。”GC”とは「Heap上で使われなくなった領域を解放してHeapを再利用することを可能とする」機能である。要は”Heap”動的メモリが足らないという事。
簡便化の為Bitmapを使用している”Tachometer”や”Dynamic Graph”描画では大量のBitmapのゴミが発生する。Bitmapの利用は描画が大変な”Tachometer”の”Gauge”に限定して、その他については(”Needle”と”Wheel”)”Canvas”に直接onDrawする手法に変更する。Memory leakは大幅に改善するが、クラッシュは改善されない。
“Memopad”端末のHeap Sizeは通常96MB、最大でも128MBしかない。埒が明かないので最終的にNexus9に買い替えることにした。
Lenovo用に再構築したアプリの稼働状況を下図に紹介する。
コードの変更等の具体的な内容は過去のThreadをRefer下さい。
年甲斐もなくのめり込み、Java定番教科書の”Effective Java”を参考にしながら何とか完成に漕ぎつけましたが、もう昔の思い出ですね。Godzilla Consult Scan ToolをAndroid機種に移管する事も可能ですが、深入りしても発展性がないので止めときます。代わりに、これまた長く放ったらかしにしているライフワークのReservoir Simulatorの共有化に向けた作業に注力する事に致します。
貴殿のご健闘を応援しています。
以上
Seize the day!
余談
Nexus9をオークションで出品するに当たって初期化する。
Kali NethunterのBoot Animationを導入していた為、単なるFactory Resetのみに終わらず、再度boot.imgをFlashする必要がある。
初期化の段階でFlashに失敗。起動できずBoot Loopになって文鎮化してしまう不運に見舞われる。原因はVersion7.1.1から5.0に一気にDowngradeしたことに原因があるのではないかと疑っている。当然Factory Resetでは倒れた警告マークドロイド君が表れてResetできず。
一度は復旧を諦めたが、シャクなのでダメ元でSideloadよりも先ずWindows版NRT(Nexus Root Tool)を試す。DownloadしたVersion7.0.0 (nrd90m)を解凍の上、所定のDefault箇所にimg zip(volantis-nrd90m-factory-fccddb6d.zip)を保存する。NRTのメイン画面から
- any version build
- Loop
Flash Stock+Unlock設定画面を押下しStock ImageをFlashする。上手くadbがDeviceを認識する。Flashできたようで正常なドロイド君が出現。その内懐かしいBoot Imageが表れる。長いなあと我慢する事10分、無事起動する。出品に向けて準備作業ヘ入る。
NRT Main画面 Image Fileの設定 Log
こう言う時はDual Bootは便利ですね。
以上