2017-01-14 51 views
1

我聽說使用位圖列表進行動畫是個不錯的主意。但是我還沒有遇到過這種情況,直到現在才證明這是真的。在Android上使用PNG進行動畫

我有很好的代碼。但只能在模擬器上或運行Android 6的手機上運行。低於此值,我會在完成初始化之前收到內存不足。

這是我如何加載在圖像:

public static Image[] flameIs = new Image[300]; 


for (int i=0;i<300;i++) { 
    if (i>=10) framePref="000"; 
    if (i>=100) framePref="00"; 
    Assets.flameIs[i] = g.newImage("frames/lighter_" + framePref +i+ ".png", ImageFormat.RGB565); 
} 

所以它像300米的PNG文件,8位,每個大約12K的大小。我們正在談論價值不到4MB的圖像。

所有應用程序以後都會在循環中永久運行這些幀。

有沒有辦法避免「內存不足」?

+0

你的位圖的平均尺寸是多少? – Gauthier

+0

它們都是459x620 – durbnpoisn

+0

然後,您的每張圖片都需要284,580字節來存儲未壓縮的數據(459 x 620 x 8位)。對於堆上的81 MB的300張圖像。 –

回答

2

300 459x620的位圖加載爲RGB_565意味着您需要300 * 459 * 620 * 2 = 171 MB的內存。

看看https://stackoverflow.com/a/9940415/3413324總結了熱門設備的堆大小,我們可以看到即使是最近的設備,您的Bitmaps也可能超出限制。

你可以做的是:

  • 降低您的位圖的大小,使他們每個人都需要在內存中

  • 更少的空間,減少您用於動畫位圖的數量,從而降低內存佔用量

  • 使用GIF,您可以使用庫加載。你可以有一個獨特的GIF的大小則直接控制文件

  • 如果可能創建動畫編程
+0

你現在得到+1。我會試試這個。我特別喜歡你鏈接的內存堆列表。我會回到這個。 – durbnpoisn

+0

我不知道如何去創建「動畫編程」。這本質上是一個作爲幀緩衝區運行的活動,即重繪的恆定狀態。意思是,它只是在一個循環中運行並刷新整個屏幕。這就是爲什麼我使用一個數組來保存接下來的幀,等等...... – durbnpoisn

+0

當你的場景由幾組移動的圖像組成時,以編程方式創建動畫會導致巨大的內存增益。即:如果只需要通過代碼移動它們而不是加載動畫的每一幀,則僅需要10個對象(位圖)移動的動畫將佔用較少的內存。 雖然並不總是可能,但總是有好的想法 – Gauthier

0

,與其建立300幀動畫,爲什麼不將它們轉換成GIF和使用類似滑翔來渲染它? (如果你不想爲你的項目添加一個新的庫,甚至可以使用webview)

它會給你更好的跨平臺控制和可移植性。

有了下滑,這將是這個樣子:

ImageView的ImageView的=(ImageView的)findViewById(R.id.imageView); GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageView); Glide.with(this).load(R.raw.sample_gif).into(imageViewTarget);

+0

如果這個程序是用XML編寫的一個活動,這將是一個選項。但是它目前的寫法是不斷重新繪製頁面。意思是說,GIF不會持續下去。不過,下次這是個好主意。 – durbnpoisn