教你怎么十秒解决百张图片帧动画oom终极骚问题

来源:互联网 发布:sql查询某表字段长度 编辑:程序博客网 时间:2024/04/30 10:08

在我们做动画的时候,为了绚丽的效果,这时候我们就要用上我们的帧动画,通过快速播放多张图片实现动画的效果,可当我图片放的太多的时候,这时候就会造成oom。为了解决这个难题,我都老了0.005岁。好了,现在我们现在正题开始。先从怎么写帧动画开始,这个很简单,我们直接秒过。

首先我们在res 目录下建立一个 anim文件夹,在里面建立我们动画xml。

<?xml version="1.0" encoding="utf-8"?><!--    根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画      根标签下,通过item标签对动画中的每一个图片进行声明      android:duration 表示展示所用的该图片的时间长度  --><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false" >    <item android:drawable="@drawable/airship_001" android:duration="180"> </item>    <item android:drawable="@drawable/airship_002" android:duration="180"> </item>    <item android:drawable="@drawable/airship_003" android:duration="180"> </item>    <item android:drawable="@drawable/airship_004" android:duration="180"> </item>    <item android:drawable="@drawable/airship_005" android:duration="180"> </item>    <item android:drawable="@drawable/airship_006" android:duration="180"> </item>    <item android:drawable="@drawable/airship_007" android:duration="180"> </item>    <item android:drawable="@drawable/airship_008" android:duration="180"> </item>     <item android:drawable="@drawable/airship_009" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0010" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0011" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0012" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0013" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0014" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0015" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0016" android:duration="180"> </item>     <item android:drawable="@drawable/airship_0017" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0018" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0019" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0020" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0021" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0022" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0023" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0024" android:duration="180"> </item>     <item android:drawable="@drawable/airship_0025" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0026" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0027" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0028" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0029" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0030" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0031" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0032" android:duration="180"> </item>     <item android:drawable="@drawable/airship_0033" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0034" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0035" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0036" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0037" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0038" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0039" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0040" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0041" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0042" android:duration="180"> </item>    <item android:drawable="@drawable/airship_0043" android:duration="180"> </item>    </animation-list>
然后我们直接在 布局xml中开始引用了

<!-- <?xml version="1.0" encoding="utf-8"?> --><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"         >    <ImageView        android:id="@+id/animation_airship"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:scaleType="centerCrop"                android:src="@drawable/animation_airship" />    <TextView        android:id="@+id/exit_airship"        android:layout_width="100dp"        android:layout_height="50dp"        android:onClick="onClickBack"        android:clickable="true"        android:text="返回"        android:layout_gravity="center_horizontal" /></FrameLayout>
这个时候我们帧动画的准备工作就完成了
这个时候 我们开始 进行我们的逻辑问题解决了,首先我们导入一个我们需要的   commons-io-1.4。jar  ,这个我们在百度上面一大堆,我也有这个,但是我就是不传给你们,哎呀,(好气呀)。

这个时候我们新建一个 工具类MyAnimationDrawable.java 他们进行复制这个工具类package com.example.demo;

package com.example.demo;import java.io.IOException;  import java.util.ArrayList;  import java.util.List;  import org.apache.commons.io.IOUtils;  import org.xmlpull.v1.XmlPullParser;  import org.xmlpull.v1.XmlPullParserException;  import android.content.Context;  import android.content.res.XmlResourceParser;  import android.graphics.BitmapFactory;  import android.graphics.drawable.AnimationDrawable;  import android.graphics.drawable.BitmapDrawable;  import android.graphics.drawable.Drawable;  import android.os.Handler;  import android.widget.ImageView;  public class MyAnimationDrawable {    public static class MyFrame {          byte[] bytes;          int duration;          Drawable drawable;          boolean isReady = false;      }        public interface OnDrawableLoadedListener {          public void onDrawableLoaded(List<MyFrame> myFrames);      }            public static void animateRawManuallyFromXML(int resourceId,              final ImageView imageView, final Runnable onStart,              final Runnable onComplete) {          loadRaw(resourceId, imageView.getContext(),                  new OnDrawableLoadedListener() {                      @Override                      public void onDrawableLoaded(List<MyFrame> myFrames) {                          if (onStart != null) {                              onStart.run();                          }                          animateRawManually(myFrames, imageView, onComplete);                      }                  });      }        //    private static void loadRaw(final int resourceId, final Context context,              final OnDrawableLoadedListener onDrawableLoadedListener) {          loadFromXml(resourceId, context, onDrawableLoadedListener);      }        //    private static void loadFromXml(final int resourceId,              final Context context,              final OnDrawableLoadedListener onDrawableLoadedListener) {          new Thread(new Runnable() {              @Override              public void run() {                  final ArrayList<MyFrame> myFrames = new ArrayList<MyFrame>();                    XmlResourceParser parser = context.getResources().getXml(                          resourceId);                    try {                      int eventType = parser.getEventType();                      while (eventType != XmlPullParser.END_DOCUMENT) {                          if (eventType == XmlPullParser.START_DOCUMENT) {                            } else if (eventType == XmlPullParser.START_TAG) {                                if (parser.getName().equals("item")) {                                  byte[] bytes = null;                                  int duration = 1000;                                    for (int i = 0; i < parser.getAttributeCount(); i++) {                                      if (parser.getAttributeName(i).equals(                                              "drawable")) {                                          int resId = Integer.parseInt(parser                                                  .getAttributeValue(i)                                                  .substring(1));                                          bytes = IOUtils.toByteArray(context                                                  .getResources()                                                  .openRawResource(resId));                                      } else if (parser.getAttributeName(i)                                              .equals("duration")) {                                          duration = parser.getAttributeIntValue(                                                  i, 1000);                                      }                                  }                                    MyFrame myFrame = new MyFrame();                                  myFrame.bytes = bytes;                                  myFrame.duration = duration;                                  myFrames.add(myFrame);                              }                            } else if (eventType == XmlPullParser.END_TAG) {                            } else if (eventType == XmlPullParser.TEXT) {                            }                            eventType = parser.next();                      }                  } catch (IOException e) {                      e.printStackTrace();                  } catch (XmlPullParserException e2) {                      // TODO: handle exception                      e2.printStackTrace();                  }                    // Run on UI Thread                  new Handler(context.getMainLooper()).post(new Runnable() {                      @Override                      public void run() {                          if (onDrawableLoadedListener != null) {                              onDrawableLoadedListener.onDrawableLoaded(myFrames);                          }                      }                  });              }          }).run();      }        //    private static void animateRawManually(List<MyFrame> myFrames,              ImageView imageView, Runnable onComplete) {          animateRawManually(myFrames, imageView, onComplete, 0);      }        //    private static void animateRawManually(final List<MyFrame> myFrames,              final ImageView imageView, final Runnable onComplete,              final int frameNumber) {          final MyFrame thisFrame = myFrames.get(frameNumber);            if (frameNumber == 0) {              thisFrame.drawable = new BitmapDrawable(imageView.getContext()                      .getResources(), BitmapFactory.decodeByteArray(                      thisFrame.bytes, 0, thisFrame.bytes.length));          } else {              MyFrame previousFrame = myFrames.get(frameNumber - 1);              ((BitmapDrawable) previousFrame.drawable).getBitmap().recycle();              previousFrame.drawable = null;              previousFrame.isReady = false;          }            imageView.setImageDrawable(thisFrame.drawable);          new Handler().postDelayed(new Runnable() {              @Override              public void run() {                  // Make sure ImageView hasn't been changed to a different Image                  // in this time                  if (imageView.getDrawable() == thisFrame.drawable) {                      if (frameNumber + 1 < myFrames.size()) {                          MyFrame nextFrame = myFrames.get(frameNumber + 1);                            if (nextFrame.isReady) {                              // Animate next frame                              animateRawManually(myFrames, imageView, onComplete,                                      frameNumber + 1);                          } else {                              nextFrame.isReady = true;                          }                      } else {                          if (onComplete != null) {                              onComplete.run();                          }                      }                  }              }          }, thisFrame.duration);            // Load next frame          if (frameNumber + 1 < myFrames.size()) {              new Thread(new Runnable() {                  @Override                  public void run() {                      MyFrame nextFrame = myFrames.get(frameNumber + 1);                      nextFrame.drawable = new BitmapDrawable(imageView                              .getContext().getResources(),                              BitmapFactory.decodeByteArray(nextFrame.bytes, 0,                                      nextFrame.bytes.length));                      if (nextFrame.isReady) {                          // Animate next frame                          animateRawManually(myFrames, imageView, onComplete,                                  frameNumber + 1);                      } else {                          nextFrame.isReady = true;                      }                    }              }).run();          }      }        //带时间的方法     public static void animateManuallyFromRawResource(              int animationDrawableResourceId, ImageView imageView,              Runnable onStart, Runnable onComplete, int duration) throws IOException,              XmlPullParserException {          AnimationDrawable animationDrawable = new AnimationDrawable();            XmlResourceParser parser = imageView.getContext().getResources()                  .getXml(animationDrawableResourceId);            int eventType = parser.getEventType();          while (eventType != XmlPullParser.END_DOCUMENT) {              if (eventType == XmlPullParser.START_DOCUMENT) {                } else if (eventType == XmlPullParser.START_TAG) {                    if (parser.getName().equals("item")) {                      Drawable drawable = null;                        for (int i = 0; i < parser.getAttributeCount(); i++) {                          if (parser.getAttributeName(i).equals("drawable")) {                              int resId = Integer.parseInt(parser                                      .getAttributeValue(i).substring(1));                              byte[] bytes = IOUtils.toByteArray(imageView                                      .getContext().getResources()                                      .openRawResource(resId));//IOUtils.readBytes                              drawable = new BitmapDrawable(imageView                                      .getContext().getResources(),                                      BitmapFactory.decodeByteArray(bytes, 0,                                              bytes.length));                          } else if (parser.getAttributeName(i)                                  .equals("duration")) {                              duration = parser.getAttributeIntValue(i, 66);                          }                      }                        animationDrawable.addFrame(drawable, duration);                  }                } else if (eventType == XmlPullParser.END_TAG) {                } else if (eventType == XmlPullParser.TEXT) {                }                eventType = parser.next();          }            if (onStart != null) {              onStart.run();          }          animateDrawableManually(animationDrawable, imageView, onComplete, 0);      }        private static void animateDrawableManually(              final AnimationDrawable animationDrawable,              final ImageView imageView, final Runnable onComplete,              final int frameNumber) {          final Drawable frame = animationDrawable.getFrame(frameNumber);          imageView.setImageDrawable(frame);          new Handler().postDelayed(new Runnable() {              @Override              public void run() {                  // Make sure ImageView hasn't been changed to a different Image                  // in this time                  if (imageView.getDrawable() == frame) {                      if (frameNumber + 1 < animationDrawable.getNumberOfFrames()) {                          // Animate next frame                          animateDrawableManually(animationDrawable, imageView,                                  onComplete, frameNumber + 1);                      } else {                          // Animation complete                          if (onComplete != null) {                              onComplete.run();                          }                      }                  }              }          }, animationDrawable.getDuration(frameNumber));      }  }
这个时候 我们就开始用这个工具类做文章了。

写个实现类;

package com.example.demo;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;public class AowerActivity  extends Activity {private ImageView animation_tower;protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.tower_activity);animation_tower=(ImageView) findViewById(R.id.animation_tower);run();}    private void run() {        // TODO Auto-generated method stub        MyAnimationDrawable.animateRawManuallyFromXML(R.drawable.animation_tower,animation_tower,null,null);    }    public void onClickBack(View v) {        finish();    }

大家要demo的可以私信我,因为demo里面的资源设计到了我的项目。



0 0
原创粉丝点击