Android逐幀動畫,逐幀動畫載入圖片過多時OOM異常的解決和替代方法
阿新 • • 發佈:2019-01-23
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每幀的影象不能過大,太大將會造成播放卡頓或閃爍等各種問題。