web-dev-qa-db-ja.com

Android背景画像のメモリ使用量

私が取り組んでいるプロジェクトでは、いくつかの「高解像度」背景を使用しています(引用に注意してください)。状況を理解するために、そのうちの1つは640x935 1.19M PNGファイルです。私の知る限り、Androidが生データとして画像をメモリに解凍する場合でも、これは次のようになります。

640 x 935 x 4バイト= 239万

私のプロジェクトでは、実際には理解できないメモリの問題があり、誰かがこの問題に光を当てることができることを願っています。開発中の2つのデバイスとその結果の一部を挙げます。

これが二次的な問題ではないことを確認するために、最初に作成されたときにバックグラウンドを読み込まないアクティビティを作成し、ユーザーがボタンを押したときに行われるのは次のとおりです。

findViewById(R.id.completed_block_background).setBackgroundResource(R.drawable.blockbackgroundbottom1);

次に、プロセスで「ヒープの更新」を使用してDDMSを使用し(最初にGCにこれが問題にならないように強制する)、次のメモリ結果が得られます。

Nexus S:18Mから26Mに移行(8Mの違い)

Galaxy Nexus:28Mから39Mへの移行(11Mの違い)

ご覧のとおり、理論的には2.39Mの非圧縮画像を背景に置くと、実際にメモリ使用量が8Mと11M増加します。誰かがこれがなぜであり、解決策があるかどうかを説明できますか?

私が見つけることができた唯一の解決策は、ビットマップを使用して解像度を半分にするか、チャネル形式を下げることです(これまでのところこれが私がしたことで、565 RGBに切り替えましたが、これは受け入れられないバンディングの問題を引き起こします)。

また、何もすることができない場合、これが起こっている理由の説明を受け入れます。前もって感謝します。

56
h4lc0n

それがイメージを非常に大きくしている理由ですか?

さて、何が起こっているのかというと、setBackgroundResource(R.drawable.blockbackgroundbottom1)が原因でAndroidが最初にBitmapFactory.decodeResource()を実行し、その後でレンダリングロジックを実行しますたとえば、Galaxy NexusとNexus Sの3MBの違いは、LinearLayoutのレンディション間のサイズの違いをピクセル単位で反映している可能性があります。

リソースツリーのどこにこの画像を保存したかに応じて、画面の密度に基づいてリサンプリングが行われる場合もあります。

何らかの方法で元の画像サイズを維持する方法はありますか?

カフから、私は最初に_res/drawable-nodpi/_に入れて(自動密度ベースのリサンプリングを防ぐために)、次にBitmapFactory.decodeResource()のバージョンを介してBitmapを手動で取得します_BitmapFactory.Options_なので、読み込み中にスケーリングできます。それがあまり役に立たない場合は、PNGを描画可能なリソースから生のリソースまたはアセットに移動する必要があります= Androidはまだ画像の拡大縮小されていないコピーを保持しようとするかもしれません。BitmapFactory.decodeResource()を自分で直接使用する場合はそうなるとは思いませんが、私はそれを排除できません。

111
CommonsWare