• 比如这个,总共77帧。下面对比三种方案

    • 方案一:

      像这样把每一帧图片放进animation-list

      1
      2
      3
      4
      5
      6
      7
      <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
      android:oneshot="false">
      <item android:drawable="@drawable/shenlie76" android:duration="83"/>
      <item android:drawable="@drawable/shenlie77" android:duration="83"/>
      <item android:drawable="@drawable/shenlie01" android:duration="83"/>
      .....
      </animation-list>

      然后

      1
      2
      3
      mIv.setImageResource(R.drawable.animation);
      Animatable drawable = (Animatable) mIv.getDrawable();
      drawable.start();

      当然是可行的,效果嘛。。看看内存吧

      一开始动画,内存占用从原来的18M飚到180M,太可怕了。我们知道初始一般会分配给一个app 十几M的内存,最多能拿200M左右,超过就OOM了,方案一唾弃之。

    • 方案二

      读取资源,使用bitmap

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      CountDownTimer countDownTimer = new CountDownTimer(300000, 83){
      @Override
      public void onTick(long millisUntilFinished) {
      if(count==imgRes.length) count = 0; //播放到最后一帧从头播放
      Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgRes[count++]);
      bitmapCache.add(new SoftReference<>(bitmap));
      mIv.setImageBitmap(bitmap);
      }
      @Override
      public void onFinish() {}
      };
      countDownTimer.start();

      还行,才占用21M,没播放时占18M,也就占了3M,一帧的bitmap对象占了3M,用完就释放掉了,不过这个锯齿也是不怎么爽的。

    • 方案三

      重用bitmap内存,避免gc频繁

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      final BitmapFactory.Options options = new BitmapFactory.Options();
      options.inMutable=true;
      CountDownTimer countDownTimer = new CountDownTimer(300000, 83){
      @Override
      public void onTick(long millisUntilFinished) {
      if(count==imgRes.length) count = 0;
      if (!bitmapCache.isEmpty()) {
      Iterator<SoftReference<Bitmap>> iterator = bitmapCache.iterator();
      if (iterator.hasNext()) {
      Bitmap bitmapSoftReference = iterator.next().get();
      Bitmap bitmap = BitmapFactory.decodeResource(getResources(),imgRes[count++],options);
      options.inBitmap = bitmapSoftReference;
      mIv.setImageBitmap(bitmap);
      }
      }else {
      Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgRes[count++], options);
      bitmapCache.add(new SoftReference<>(bitmap));
      mIv.setImageBitmap(bitmap);
      }
      }
      @Override
      public void onFinish() {}
      };
      countDownTimer.start();

      完美。