热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android使用帧动画内存溢出解决方案

这篇文章主要介绍了Android使用帧动画内存溢出解决方案的相关资料,这里提供了详细的解决办法,具有参考价值,需要的朋友可以参考下

Android 使用帧动画内存溢出解决方案

最近在项目遇到的动画效果不好实现,就让UI切成图,采用帧动画实现效果,但是在使用animation-list时,图片也就11张,每张图片大概560k左右,结果内存溢出,崩溃 了,自己用了三张都崩溃;拿代码说;

1.anin_searh.xml

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
  
   
   
   
   
   
   
   
   
   
 

2.使用帧动画

search_scale_iv.setBackgroundResource(R.drawable.anim_search); 
    AnimationDrawable drawable = (AnimationDrawable) search_scale_iv.getBackground(); 
    drawable.start(); 

结果setBackgroundResource出现内存溢出,这个方法其实获取drawable时候,会消耗很多内存,很容易内存溢出,崩溃。

3.解决方法:在网上找了个类,处理,结果我使用11张560k大小图片,没有内存溢出;

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; 
 
import org.apache.commons.io.IOUtils; 
import org.xmlpull.v1.XmlPullParser; 
import org.xmlpull.v1.XmlPullParserException; 
 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
 
/**** 
 * 此工具类源于stack over flow 
 * 原文链接:http://stackoverflow.com/questions/8692328/causing-outofmemoryerror-in-frame-by-frame-animation-in-android 
 * 主要使用了BitmapFactory.decodeByteArray方法通过底层C来绘制图片,有效防止OOM 
 * 使用了第三方类库:org.apache.commons.io.IOUtils,将Inputstream转为byte字节数组 
 * *******/ 
public class MyAnimationDrawable { 
 
  public static class MyFrame { 
    byte[] bytes; 
    int duration; 
    Drawable drawable; 
    boolean isReady = false; 
  } 
 
  public interface OnDrawableLoadedListener { 
    public void onDrawableLoaded(List myFrames); 
  } 
 
  // 1 
  /*** 
   * 性能更优 
   * 在animation-list中设置时间 
   * **/ 
  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 myFrames) { 
            if (onStart != null) { 
              onStart.run(); 
            } 
            animateRawManually(myFrames, imageView, onComplete); 
          } 
        }); 
  } 
 
  // 2 
  private static void loadRaw(final int resourceId, final Context context, 
                final OnDrawableLoadedListener onDrawableLoadedListener) { 
    loadFromXml(resourceId, context, onDrawableLoadedListener); 
  } 
 
  // 3 
  private static void loadFromXml(final int resourceId, 
                  final Context context, 
                  final OnDrawableLoadedListener onDrawableLoadedListener) { 
    new Thread(new Runnable() { 
      @Override 
      public void run() { 
        final ArrayList myFrames = new ArrayList(); 
 
        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  myFrames, 
                      ImageView imageView, Runnable onComplete) { 
    animateRawManually(myFrames, imageView, onComplete, 0); 
  } 
 
  // 5 
  private static void animateRawManually(final List 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 

这里需要导入jar,

import org.apache.commons.io.IOUtils;

4.然后通过上述类,来调用自己的动画xml,

MyAnimationDrawable.animateRawManuallyFromXML(R.drawable.anim_search, 
            search_scale_iv, new Runnable() { 
 
              @Override 
              public void run() { 
                // TODO onStart 
                // 动画开始时回调 
                log.d("","start"); 
                 
              } 
            }, new Runnable() { 
 
              @Override 
              public void run() { 
                // TODO onComplete 
                // 动画结束时回调 
                log.d("","end"); 
                 
              } 
            }); 

这样在使用帧动画时,可以有效的适度防止内存溢出,谁还有什么办法,欢迎交流!

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


推荐阅读
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文是关于自学Android的笔记,包括查看类的源码的方法,活动注册的必要性以及布局练习的重要性。通过学习本文,读者可以了解到在自学Android过程中的一些关键点和注意事项。 ... [详细]
  • 突破MIUI14限制,自定义胶囊图标、大图标样式,支持任意APP
    本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
author-avatar
fuhuan9479184787
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有