状況:
現在、実解像度854x480、dipでは569x320の端末でアプリケーションを開発しております。
この際に背景やImageボタンの素材に使う画像についてなのですが、
たとえば背景画像ですと、569x320のものを使いますと、拡大されますので当然のことながら画像が荒くなります。
854x480のものを使いますと綺麗にはなるのですが、さらに大きい画像を使うとより綺麗になる感じがします。
感覚的には、実端末の1.5倍(1281x720)程度の素材までは画質が向上し、
それ以上はそんなに変化がないように見えます。
そのため、基本的に実端末の1.5倍(dip指定の縦横3倍)の画像素材を用いる方向で
開発を進めております。
しかしながら、この状態でカメラで撮影した写真画像や、インターネットサーバからダウンロードした
多数の画像(200kb x 30個以上)を扱おうとすると、高頻度で OutOfMemoryError
(bitmap size exceeds VM budget)が発生してしまいます。
ここで過去の投稿にありますように、(ImageView)view.setImageDrawable(null); を積極的に行っていけば
OutOfMemoryError が発生しにくくなるようです。
また使用する画像素材のサイズを小さいものに変えただけでも、OutOfMemoryError が発生しにくくなりました。
そのため、大きい画像素材が OutOfMemoryError の一因になっていると考察しております。
そこで今回のアプリでは複数のActivityを使用しますので、改善の方向性としては
onResume()で画像素材を読み込み、onPause()で画像の解放を行うように改修することで
表示されていない画面の画像素材についてはGC対象となることから、
OutOfMemoryError が発生しなくなるのでは、と考えております。
質問事項:
・綺麗な画像を表示するために、dip指定の縦横3倍の素材を使うという方法は適切でしょうか。
・OutOfMemoryError に対する対応策として、上記は妥当でしょうか。
またよりよい方法がありそうでしょうか。
(なお、インターネットサーバからダウンロードした多数の画像を扱う部分については、
サムネ情報を扱うように変更するなどの設計変更を検討しております)
皆様のお知恵を拝借したいと思っております。よろしくお願いいたします。
--
宮腰 茂明(MIYAKOSI Sigeaki)
miyakosi...@gmail.com
http://sites.google.com/site/miyakosis/
--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
KobadroID様
> メモリ不足には私も悩みましたが、結局一番効果あったのは
> 画像サイズの縮小でした。特に背景のように大きなビットマップは
> 最も削りました。
> BitmapConfigを調整してメモリサイズを縮小する等もそれなりに
> 効果がありました。
サイズと仰っているのは、ピクセル数のことかと思います。
たしかに高解像度で準備した方がよい素材を吟味し、
それ以外は低解像度にする方針で今後進めてみます。
また、もしかして素材画像の色数を減らす(詳しくないのですがPNG-8等?を使う)のも
効果があるかもしれない、と試したいところです。
BitmapConfigについては、BitmapFactory.decodeFile()等で作成したbitmapに対して、
Bitmap bitmapNew = bitmap.copy(Bitmap.Config.RGB_565, true);
bitmap.recycle();
とするのかな、と考えております。
(createするタイミングではRGB_565は指定できない、ですよね?)
オブジェクトが実際に占有しているメモリ量が実測できれば
調査の参考になると思うのですが、調べ方が分からないため、
手探りでトライアルしている状況です。
DDMSのHeapタブなどの情報を見てもよくわからない
(Bitmapで使用しているメモリ情報が載ってこないように見える?)のですが、
メモリサイズを実測方法など、どなたかご存知ないでしょうか?
tshinsay様
> ・画面解像度より大きな画像を用意することについて
> 基本的にピクセル等倍である場合、意図した見た目≒綺麗な見た目になるはずです。
> 補間してボケた画像が綺麗と錯覚してるか、あるいはdip計算時に微妙に座標が狂っているように思えます。
> 前者はともかく、後者はpx指定すれば解決すると思います。
もしかしたらdip指定だと必ず拡大等の処理が入ってしまい、
画質の低下を招いているのかもしれません。
px指定というのは、気がつきませんでした。
確かに現状では解像度ごとにlayoutファイルを作成しなければいけない画面も
多数ありますので、どの道別々にlayout作成するのであればpx指定もアリな気がします。
試してみます。
> よって少メモリ環境での根本的な解決策としては、オンデマンドで読み込み、不要になった画像は
> 不要になり次第GCではなく、自分で開放することです。
そうですね、一覧画面で画像に解像度が必要ないのは仰るとおりですので、
一覧画面用にサムネ画像を作成するなどの処理を今後入れていこうと考えております。
なお画像のメモリ解放の具体的な方法について、
Bitmapに対しては recycle() を呼ぶと思うのですが、
Drawableに対しては解放するメソッドがちょっと分かりませんでした。
どのように解放するか、ご教示いただけないでしょうか?
よろしくお願いいたします。
2011年7月2日13:03 t.shinsay <t.sh...@gmail.com>:
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
>
--
tshinsay様、ふたたびご回答ありがとうございました。
画像系のメモリはddmsで見られるヒープの外に確保される?みたいで、
解放漏れの調査が大変です。解析する良いツールがあるといいんですけれども・・・
2011年7月3日9:55 t.shinsay <t.sh...@gmail.com>:
bitmap.recycle();
とするのかな、と考えております。
(createするタイミングではRGB_565は指定できない、ですよね?)
下記のサイトは参考になりませんでしょうか。
d.hatena.ne.jp/hidecheck/20110625/1309024778
d.hatena.ne.jp/hidecheck/20110626/1309100335
後、bitmap.recycle();は、gcしてもいいよという命令だと思いますので、こ
の後、bitmapを開放した後、System.gc()として、明示的にgcを走らせてはダメ
でしょうか。
失礼しました。
(2011/07/03 23:51), MIYAKOSI Sigeaki wrote:
> 宮腰です。
>
> tshinsay様、ふたたびご回答ありがとうございました。
>
> 画像系のメモリはddmsで見られるヒープの外に確保される?みたいで、
> 解放漏れの調査が大変です。解析する良いツールがあるといいんですけれども・・・
>
>
> 2011年7月3日9:55 t.shinsay<t.sh...@gmail.com>:
>> tshinsayです。
>>
>> ソースを読んでわけでは無いので詳しくは分かりませんが、ドキュメントを見る限り
>> Bitmap等の実体をラップするだけのクラスで、内部情報的にはジオメトリ系の情報とBitmap等実体
>> への参照から構成されると考えられます。よって開放メソッドは無いと思われます。
>> 例えばBitmapDrawableの場合でしたら、中のBitmapを開放してあげると目的は達せられる
>> と思います。
>>
>> エラーメッセージを見る限り、Bitmapの場合のみ特別な領域を確保しているように見えますので、
>> Bitmapさえ適切に開放すれば、後はGCに任せて大丈夫でしょう。
>>
>> --
>> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
>> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
>> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
>> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>>
>>
>
>
>
--
山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
E-Mail: taro...@gmail.com
kobadroid様、たろサ様、コメントありがとうございます。
素材画像の解像度についてその後試したところ、ScaleDensity 1.5の端末において
実液晶の解像度と同じdip指定である1.5倍のものがもっともバランスがいいように見えますので、
今後1.5倍のもので作成していく方針を考えております。
(2倍以上の画像は、気持ちシャープに見える気がしますが、縮小アルゴリズムが
たまたま綺麗に見える方向に働いただけかもしれません)
これはtshinsay様よりご指摘いただいた内容の通りです。
前に2倍や3倍の画像の方が綺麗に見えた気がしたのはちょっと謎です。
使われている色合いや文字の有無とかでも、すこし変わってくるのかもしれません。
recycleをそれなりの速度で繰り返すとoutofmemoryが発生するというのは、
以下は私の推測ではありますが、
GCが走るタイミングとの関係で、連続した大きな空き領域がない状態で
比較的大きいメモリを要求してoutofmemoryになるのでは、と考えています。
ただ下記サイトによると「オブジェクトのアロケートに失敗したときもGC が
実行される」とありますので、ちょっと私の仮説とは合いません。
http://www.adamrocker.com/blog/246/overview-of-the-dalviks-gc.html
なおたろサさんのご提示いただいたサイトは大変参考になりました。
ありがとうございました。
2011年7月4日1:01 たろサ <taro...@gmail.com>:
--