ベテラン・プログラマの密かなつぶやき

日々の仕事で得たプログラミングの知識を咀嚼してまとめています

Android TextVewが遅い

再び、Androidアプリ開発のお話です。

画面を構成するときにテキストを表示するコンポーネントとしてTextViewはよく使われる物の一つだと思う。

しかしこれが使い方によって画面を非常に重くさせてしまう。

多分、これが内部で保持している文字列に問題があるのだと思うのだが、この文字列を定期的にスレッドで更新をかけて表示内容を変えていくというシステムを作った時に、ある期間を過ぎたあたりから画面が非常に重くなり、ボタンも効かなくなって非常に困った。

TextViewで保持している文字列はべたな文字列で単純に追加していくと、特定の位置を調べるのにいちいち文字列検索してやらないといけなくなる。

多分それが負荷を大きくする原因なのだろう。この文字列を外部でArrayListに保存して行単位に管理できるようにして、行の位置を簡単にとらえられるようにしただけで、この問題は解消した。

ただTextViewに入れる文字列を最大100行ぐらいで押さえておかないと、やっぱり重くなる。

文字列の連結に時間がかかっているのか、TextView内での画面表示に時間がかかっているのか、そこはよくわからなかった。

もう少しすっきりとした解答を得たかったが、今回は時間がなくこれで良しとした。

まだまだ奥が深い。

 

Android 画像のファイル保存

AndroidStudioでAndroidアプリのお仕事をさせてもらっている。やはり受注の仕事は自分で頭をひねる必要がない分楽。アイデアをひねり出すという作業はそう簡単に習慣化できるものではない。どうしても安易な方向に動いてしまう。

 

ということで、今やっている仕事はそれなりに楽しい。

コーディングでわからないことがあればWeb検索すれば大抵記事が載っていてサンプルコードをコピペすればそれなりに動いてくれる。

それでもいくら調べてもなかなかいい情報が得られず苦悶することもある。

 

画像のファイル保存もそうだった。ピクセルがbyte配列に入っていてそれを画像ファイルとして保存したかったのだが、byte配列をビットマップに変換する、で検索すると

 

Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
 

というコードが出てくるのだが、確かに間違いではない。ただ条件があってその記述がどこにも書かれていない。自分が到達した結論は、ここで使われているbyteArrayにはビットマップヘッダ情報が含まれていなければいけない、ということ。

しかし、やりたいのはbyteArrayにはピクセル情報だけ入っている場合の変換。

結局、ビットマップオブジェクトを作成してピクセル単位にbyte配列の情報を代入してやるしかない、ということが分かった。

 

Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int i = 0; i < byteArray.length; i++) {
    int gray_data = byteArray[i] & 0xFF;
    int gray_argb = Color.argb(255, gray_data, gray_data, gray_data);
    bmp.setPixel(i%width, i/width, gray_argb);
}

 

ちょっと苦労したけど、わかってみれば確かにそう考えるのが当たり前。安易に一括で処理してくれる関数はないかと考えたのが甘かった。

 

しかし、時々こういう不親切な情報が中途半端にしか出ていない記事も多く、悩ましい。

 

そういう隙間を埋める記事をここに書くことができれば、このブログの意味もあるのかもしれない。

 

考えがまとまらない

イデアが頭の中で渦巻いているのだが、それが思うようにまとまっていかない。

とりあえず、プロジェクトを立ち上げて画面を作成し、そこにひとつづつ機能を埋め込んでいる状況。まったくまとまりがない。

自分で言うのも何だが、このツール、思い通りのものができればいいものになる気がするのだけれど。

ちょっとアイデアを言葉にしてみると、PC内にある様々な情報をタブで一括管理するという感じ。タブで情報を紐づけするという感覚は直感的でわかりやす気がするのだけれど、どうだろう?

ちょっと体調も良くなく、先週はほとんど寝込み状態だったので、このブログ記事も手を付けられずにいた。まだ本調子ではないが、少しづつでもアウトプットしていこうと思う。

気長にツールづくりに付き合ってもらえればと思っている。

 

GitHub登録

先週作成したプロジェクトをGitHubに登録した。

GitHub - YoshimiMasaaki/openCV_C-

ただ本当に簡単なプロジェクトだけになってしまった。

これからいろいろな応用は考えていくつもりだが、なかなかそのアイデアが浮かばない。

このプロジェクトの注意点だけ一覧しておく。

openCVは入っていないのでインストールは調べて入れてください。

openCVのインストール先のincludeやlibフォルダは合わせてください。

・プロジェクト内のDLLをC#から見えるようにするためには参照設定が必要です。

以上。

 

今週は体調不良であまり仕事が進みそうにない。

とりあえず、雑誌インターフェースの記事を参考にそれらしい画像処理を実装してみようとは思っている。

 

画像処理、はじめの一歩

c++c#を使って何を作るか。やっぱり画像処理でしょう。

仕事の実績を棚卸したところでも結構画像処理には縁があった。

そして画像処理といえば今では定番となったopenCVを使いこなすことが必須となる。

構成は画面周りをc#で作成してc#からopenCVを呼び出し、その結果をc#の画面に反映させるという感じが自分にとってはしっくりくる。

c#からダイレクトにopenCVを呼び出すことができないので間にラッパーを挟み込む。手法はいくつかあるようだが、c++/CLIのDLLを作成してc#から作成したDLLを呼び出し、DLL経由でopenCVにリーチするというやり方。面倒だが一度作ってしまえば適用範囲は広いのでプロジェクトの構成はこれで決まった。

次にDLL内に作成するクラスだが、ここでかなり苦労した。わかってしまえばすべてメモリ管理の話になるのだが、マネージドクラスだとか参照クラスだとか、あるいはgcnewやrefなどキーワードがいっぱい出てきてかなり焦った。結局確保したメモリの管理で開放を明示するかガベージコレクションに任せるかという話に過ぎないことがわかって頭を切り替えてとにかくこう記述しないといけないのだという理解だけでコーディング。

ちょっと強引だったが何とか1日で画像をファイルから読み込んでopenCVで加工し、その結果をc#の画面に表示させることまではできた。ちょっとソースが汚いので公開はまだ先に延ばすが、GitHubにでも登録して公開はするつもり。

こういうプロジェクトが1つ手元にあればそれだけで武器になると思う。問題はそれを使って最終的に何がしたいかなんだけど。次のステップはカメラ画像に挑戦するということだけ宣言しておく。

 

 

 

 

次のステップを考える

Android JAVA の仕事がいったん落ち着いたので、今日は今までの技術経験の棚卸とオン後の展望について考察。

 

長くこの仕事についているだけに経験は豊富でそこだけは自慢できる。分野も幅が広い。MS-DOSからWindowsUNIXメインフレームLinuxiTRONとなんでも取り組んできた。言語も様々で結構器用なんだと自分でもそう思う。

 

ただ、幅が広すぎでアピールポイントがあいまいになってしまっている。何でも屋ではとらえどころがなく自分を売り込むのにもぼやけてしまう。

 

しかし棚卸をしてやっぱり自分はMicrosoftとともにあることをいまさらながらに実感している。今後はこの線で絞って自分のスキルを磨いていく。

 

手始めがc++c#。これらの言語を使いこなせればWindowsの仕事は大抵自信をもって提案できるはず。と取り組み始めたはいいが、最初から悩みまくり。その七転八倒の経緯が今後のこのブログのメイン記事となりそうです。

画面設計からロジック設計へ

アプリを作成するにあたってイベントドリブンは当たり前の世界になっているが、Android JAVA も例外ではない。

 

昨日までの画面作成から打って変わって、今日はイベントロジックのコーディングに取り組んだ一日となった。こういう内部ロジックについては比較的組みやすい。自分の得意とするところでもある。ということで、今日は技術的な課題に苦しんだということはなかった。

 

それにしてもプログラミング言語の情報に関しては、ネット検索すれば簡単に得ることができる。アプリ開発に関しては本当に便利な世の中になった。ただそのおかげでアプリの中身もかなり複雑になってしまったが。