教你怎么十秒解决百张图片帧动画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
- 教你怎么十秒解决百张图片帧动画oom终极骚问题
- 使用SurfaceView加载多张大分辨率图片做帧动画,解决OOM问题
- android图片的三级缓存原理demo,解决图片加载OOM的问题,能加载上万张图片
- retrofit2+Executors+DiskLruCache 2秒加载100张图片从此告别OOM的困扰
- retrofit2+Executors+DiskLruCache 2秒加载100张图片从此告别OOM的困扰
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题
- 解决Android解析图片的OOM问题
- 解决Android解析图片的OOM问题
- 解决Android解析图片的OOM问题!!!
- 解决Android解析图片的OOM问题!!!
- 记一次Mock100万数据到数据库遇到的问题
- 本人在学习笔记
- Git版本控制工具在Android Studio中的使用
- Hadoop之HDFS客户端的权限错误:Permission denied
- 创建一个Android程序
- 教你怎么十秒解决百张图片帧动画oom终极骚问题
- 函数指针和指针函数 区别
- 整合Struts2,Hibernate和Spring的一个简单例子
- JavaScript笔记整理 —— XMLHttpRequest对象
- frameset布局时frame中src路径的页面没有加载的解决方法
- HBuilder webApp开发(九)首次启动轮播页的制作
- 在android下使用opencv
- MPU9250配置及原始数据读取
- leetcode 139 Word Break