1. 程式人生 > >Android逐幀動畫,逐幀動畫載入圖片過多時OOM異常的解決和替代方法

Android逐幀動畫,逐幀動畫載入圖片過多時OOM異常的解決和替代方法

1.首先新增逐幀動畫

播放逐幀動畫,在工程中res目錄下建立一個anim資料夾,新增動畫anim_welcome.xml檔案如下:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/meet_01" android:duration="500" />
    <item
android:drawable="@drawable/meet_02" android:duration="500" />
<item android:drawable="@drawable/meet_03" android:duration="500" /> </animation-list>

之後,為ImageView控制元件設定動畫,並可看到想要的逐幀動畫的效果:

    ImageView imgView_meet =(ImageView)findViewById(R.id.imgView_meet);
    imgView_meet.setBackgroundResource(R.anim.anim_meet);
    AnimationDrawable animDrawable = (AnimationDrawable)imgView_meet.getBackground();
    animDrawable.start();

2.Android逐幀動畫造成OOM異常

由於逐幀動畫載入的圖片很多,不一定只有2/3張,很可能達到10張以上甚至幾十張,易造成OOM異常崩潰的問題,解決方法如下。

方法一:

(各種百度->發現幀動畫一次性載入10張圖片,易造成OOM,故修改成分佈載入10張圖片,不說了,直接上程式碼:)

package com.child.drawdemo;

import android.widget.ImageView;

public class SceneAnimation {
    private ImageView mImageView;
    private int[] mFrameRess;
    private
int[] mDurations; private int mDuration; private int mLastFrameNo; private long mBreakDelay; public SceneAnimation(ImageView pImageView, int[] pFrameRess, int[] pDurations) { mImageView = pImageView; mFrameRess = pFrameRess; mDurations = pDurations; mLastFrameNo = pFrameRess.length - 1; mImageView.setBackgroundResource(mFrameRess[0]); play(1); } public SceneAnimation(ImageView pImageView, int[] pFrameRess, int pDuration) { mImageView = pImageView; mFrameRess = pFrameRess; mDuration = pDuration; mLastFrameNo = pFrameRess.length - 1; mImageView.setBackgroundResource(mFrameRess[0]); playConstant(1); } public SceneAnimation(ImageView pImageView, int[] pFrameRess, int pDuration, long pBreakDelay) { mImageView = pImageView; mFrameRess = pFrameRess; mDuration = pDuration; mLastFrameNo = pFrameRess.length - 1; mBreakDelay = pBreakDelay; mImageView.setBackgroundResource(mFrameRess[0]); playConstant(1); } private void play(final int pFrameNo) { mImageView.postDelayed(new Runnable() { public void run() { mImageView.setBackgroundResource(mFrameRess[pFrameNo]); if (pFrameNo == mLastFrameNo) play(0); else play(pFrameNo + 1); } }, mDurations[pFrameNo]); } private void playConstant(final int pFrameNo) { mImageView.postDelayed(new Runnable() { public void run() { mImageView.setBackgroundResource(mFrameRess[pFrameNo]); if (pFrameNo == mLastFrameNo) playConstant(0); else playConstant(pFrameNo + 1); } }, pFrameNo == mLastFrameNo && mBreakDelay > 0 ? mBreakDelay : mDuration); } }

之後,並可以對上述類進行呼叫(首先定義一堆要載入的圖片,之後呼叫類的建構函式即可):

    private int[] meetPics = new int[]{
                R.drawable.meet_01, R.drawable.meet_02, R.drawable.meet_03, 
                R.drawable.meet_04, R.drawable.meet_05, R.drawable.meet_06,
                R.drawable.meet_07, R.drawable.meet_08, R.drawable.meet_09,
                R.drawable.meet_10, R.drawable.meet_11, R.drawable.meet_12,
                R.drawable.meet_13, R.drawable.meet_14, R.drawable.meet_15,
                R.drawable.meet_16, R.drawable.meet_17, R.drawable.meet_18,
                R.drawable.meet_19, R.drawable.meet_20, R.drawable.meet_21,
                R.drawable.meet_22, R.drawable.meet_23, R.drawable.meet_24,
                R.drawable.meet_25, R.drawable.meet_26, R.drawable.meet_27,
                R.drawable.meet_28, R.drawable.meet_29, R.drawable.meet_30,
                R.drawable.meet_31, R.drawable.meet_32, R.drawable.meet_33,
                R.drawable.meet_34, R.drawable.meet_35, R.drawable.meet_36,
                R.drawable.meet_37, R.drawable.meet_38, R.drawable.meet_39,
                R.drawable.meet_40, R.drawable.meet_41, R.drawable.meet_42,
                R.drawable.meet_43, R.drawable.meet_44, R.drawable.meet_45,
                R.drawable.meet_46, R.drawable.meet_47, R.drawable.meet_48,
                R.drawable.meet_49};

    SceneAnimation anim = new SceneAnimation(imgView_meet, meetPics, 40);

方法二:(直接載入gif動畫達到效果)

【其中可採用如下兩種方式】

1.直接採用GitHub上的gif開源框架:

android-gif-drawable的原始碼下載地址:https://github.com/koral--/android-gif-drawable

2.利用WebView控制元件,將gif動畫檔案作為web的一部分進行載入:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
private WebView webView;
----------
webView = (WebView)findViewById(R.id.webView);
webView.loadDataWithBaseURL(null,"<HTML><body><div align=center><IMG src='file:///android_asset/play.gif'/></div></body></html>", "text/html", "UTF-8",null);

採用上述各種方法來達到幀動畫的效果時,圖片或gif每幀的影象不能過大,太大將會造成播放卡頓或閃爍等各種問題。