Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源

时间:2022-09-10 10:15:18

2015年项目接到一个需求,实现一个向导动画,这个动画一共六十张图片,当时使用的是全志A33的开发(512的内存),通过使用Android的动画集实现,效果特别卡顿,然后想到这样的方式来实现,效果非常流畅.然后写成开一个开源项目供大家參考

对照下面两种方式实现帧动画,使用同样的80张280x280的png图片运行动画,资源占用情况对照:

Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源

Android动画集实现: 内存占用56M左右

FrameAnimation实现: 内存占用4M左右

两者CUP占用都比較低,可忽略

博客地址:

http://blog.csdn.net/qq_25804863/article/details/65634864

代码地址:

https://github.com/ansen360/FrameAnimation

Sample效果:

Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源

//bbsmax.ikafan.com/static/L3Byb3h5L2h0dHAvb21hNjg5azhmLmJrdC5jbG91ZGRuLmNvbS9ub3RlLzMvNC5naWY=.jpg

Android动画集实现帧动画

  • 1 在drawable文件夹下创建动画集animalist.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false"> <!--通过Android动画集播放的八十张图片-->
<item
android:drawable="@mipmap/c_1"
android:duration="50" />
<item
android:drawable="@mipmap/c_2"
android:duration="50" />
<!-- 省略... -->
<item
android:drawable="@mipmap/circle_19"
android:duration="50" />
<item
android:drawable="@mipmap/circle_20"
android:duration="50" /> </animation-list>
  • 2 在布局文件ImageView中使用该drawable
<?xml version="1.0" encoding="utf-8"?

>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ansen.frameanimation.sample.MainActivity"> <ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/animlist" /> </LinearLayout>
  • 3 在代码中调用,启动动画
    ImageView image = (ImageView) findViewById(R.id.image);

    AnimationDrawable animationDrawable = (AnimationDrawable) image.getDrawable();
animationDrawable.start();

动画启动系统资源占用情况例如以下:

Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源

手动触发GC,内存占用差点儿没改变

FrameAnimation实现帧动画

  • 1 定义须要播放动画的资源文件;在arrays文件里定义资源,或者在代码中定义
<?

xml version="1.0" encoding="utf-8"?>
<resources> <!--通过FrameAnimation播放的八十张图片-->
<array name="c"> <item>@mipmap/c_1</item>
<item>@mipmap/c_2</item>
<!-- 省略... -->
<item>@mipmap/circle_19</item>
<item>@mipmap/circle_20</item>
</array> </resources>

获取定义之后的资源数组(代码中可直接定义资源文件的数组,便可忽略上一步):

    private int[] getRes() {
TypedArray typedArray = getResources().obtainTypedArray(R.array.c);
int len = typedArray.length();
int[] resId = new int[len];
for (int i = 0; i < len; i++) {
resId[i] = typedArray.getResourceId(i, -1);
}
typedArray.recycle();
return resId;
}
  • 2 在代码中调用,启动动画
    ImageView image = (ImageView) findViewById(R.id.image);

    FrameAnimation frameAnimation = new FrameAnimation(image, getRes(), 50, true);
frameAnimation.setAnimationListener(new FrameAnimation.AnimationListener() {
@Override
public void onAnimationStart() {
Log.d(TAG, "start");
} @Override
public void onAnimationEnd() {
Log.d(TAG, "end");
} @Override
public void onAnimationRepeat() {
Log.d(TAG, "repeat");
}
});

动画启动系统资源占用情况例如以下:

Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源

手动触发GC,内存占用有明显变化