A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 武汉分校-小舞 于 2016-3-18 11:16 编辑

【武汉校区】独家分享:Android的有关内存性能的总结

        作为一名Android开发人员,我们都知道Android系统对每个软件所能使用的RAM空间进行了限制(如:Nexus one 对每个软件的内存限制是24M),同时Java语言本身比较消耗内存, dalvik虚拟机也要占用一定的内存空间。所以,在这里我就跟大家聊一聊在Android开发当中遇到的有关内存优化方面的个人总结,仅仅是个人总结….如果你有不同意见,请大家各自保留。那么,对于Android的内存优化,我个人总结出了一个基本准则
第一:不要做不必要的事。第二:不要分配不必要的内存。
       下面,我就基于这2点准则,为大家列举一下开发当中所需要的一些点:
那么首先,我们都知道开发Android程序的IDE工具有eclipse、idea以及google新推的android studio…那么从开发的工具选择上呢,我建议大家使用studio工具,至于原因的话,相信我不用多少,大家都能够明白? 谁能对自己的亲儿子不多加照顾呢? 那么好的,确定了开发的IDE工具之后,那么在开发过程当中,我个人所遇到的一些跟内存优化相关的技术点,来跟大家一一罗列一下吧…
First:
避免创建不必要的对象,特别是for循环里当中组装数据到集合当中的时候,每一次for循环都new出来一个对象,从而每一次都创建了一个这个对象的引用,这种做法不太好,而我们通常大多数在编写代码的时候,都会这么写,请看示例代码:
for (int i = 0; i < datas.length; i++) {
    Product bean = new Product();
    //.....set.set
   
}
优化后的写法:
Product bean = null;
for (int i = 0; i < datas.length; i++) {
    bean = new Product();
    //.....set.....set
    //list集合加入当中
    list.add(bean);
}
Two:尽量多使用静态方法调用,静态调用比普通方法调用要快,因为调用静态方法可以无需创建对象,在执行效率上更高。
Three:Android当中bean对象定义,避免使用gettters/setters,可以将变量定义成public直接访问比调用getters/setters更加高效些。
那么就直接上代码吧,在我们习惯的变成开发中,定义bean通常对象是这样的:
public class Image {

    private String ID;

    private  String IMAPAURL;

    private String IMAURL;

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getIMAPAURL() {
        return IMAPAURL;
    }

    public void setIMAPAURL(String IMAPAURL) {
        this.IMAPAURL = IMAPAURL;
    }

    public String getIMAURL() {
        return IMAURL;
    }

    public void setIMAURL(String IMAURL) {
        this.IMAURL = IMAURL;
    }
}
个人优化后的写法:
*/
public class Image {

    public String ID;

    public String IMAPAURL;

    public String IMAURL;
}
简单,代码量少,而且执行效率更高。
Four:尽量多利用缓存
这个我相信不用多少了,就拿我写的其中一个viewpagerAdapter适配器来说吧,当我需要适配出来几千甚至上万张图片的时候,我但是不能用上万个ImageView对象去做了,这是我利用缓存的适配器代码,大家可以参考:
public class PlayingAdapter extends PagerAdapter {

    private Context context;
    private List<MediaSession.QueueItem>queue;

    private List<ImageView> cache = new ArrayList<>();

    public PlayingAdapter(Context context, List<MediaSession.QueueItem>queue) {
        this.context = context;
        this.queue = queue;
    }

    @Override
    public int getCount() {
        return queue == null ? 0 : queue.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        //从缓存当中查一下,如果缓存有图片的话,直接使用缓存的,使用完毕之后,再从缓存集合当中移除
        //如果缓存没有的话,new一个
        ImageView result = null;
        if(cache.size()==0){
            result = new ImageView(context);
            result.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }else{
            result = cache.remove(0);
        }
        Picasso.with(context).load(queue.get(position).getDescription().getIconUri()).into(result);
        container.addView(result);
        return result;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((ImageView)object);
        cache.add((ImageView) object);
    }

    public void flushData(List<MediaSession.QueueItem>queue) {
        this.queue = queue;
        notifyDataSetChanged();
    }
}
Five:定义常量尽量多使用static final,避免使用枚举,普通成员变量避免过多的使用static关键子,特别是Context, 如果用它来引用一些资源耗费过多的实例。
在java中枚举类的过多使用会降低程序的执行效率,从而影响我们开发当中的软件性能,所以应该尽量避免过多的使用枚举类,如果是常量的话,可以多使用static final ,但是如果是普通变量,应该必变过多的使用static修饰,因为静态变量如果没有被销毁或者设置为null,它的引用一直存在,如果过多的有这种情况出现,就会导致内存泄露的问题了,而且如果经常使用static的Bitmap、Drawable等变量。可能就会抛出一个在Android系统中非常著名的异常(以前budget这个单词一直记不住什么意思,自从经常抛出这个异常后,这个单词终于烂熟于心了
ERROR/AndroidRuntime(4958): Caused by: java.lang.OutOfMemoryError:bitmap size exceeds VM budget
six:资源对象必须关闭,SQLiteOpenHelper,cursor,文件,i/o流等等
相信这个都不用多说了,我个人总结一点,所有使用了操作流数据的对象使用完毕后,统统都需要关闭。
Seven:bitmap大图片用完需要recycle回收,并设置为null,方便gc回收
这个相信大家也都比较熟悉了,其实不止是bitmap,Android当中TypedArray对象等等,使用完毕之后,都是建议我们调用recycle方法进行回收的,只是容易被大家忽略的是,将其设置为null,当然这个不是一定的,要根据你的具体情况来定了,如果你不需要再使用到它的话,就将其设置为null….让gc来回收掉它吧…
Eight:注册广播接收者,必须取消反注册,避免内存泄露。
这个我相信大家也都知道,每每调用registXX---那么千万要养成好的习惯,在onDestory当中进行反注册 unRegistXX….,那么如果不这样写的话,就会出现内存泄露的问题了。
Nine:listview的列表优化都需要做等等。
相信这个不需要我再废话多少了…就是利用缓存机制,那么我总结一点的就是,当使用listview开发真实的app项目的话,都必须要做优化…
以上就是本人对于Android开发当中的内存性能的几点总结了,希望提供大家参考,为程序员同胞们能带去帮助。

想最快获传智播客武汉中分享技术文章请加QQ  1641907557 ,后期会分享更多与实体班同步教程,助你冲击月薪20K!


推荐阅读:


3 个回复

倒序浏览
收藏了。。暂时还看得云里雾里,不过很多原则所有编程都适用
回复 使用道具 举报
ameanboy 发表于 2016-3-18 12:12
收藏了。。暂时还看得云里雾里,不过很多原则所有编程都适用

回复 使用道具 举报
顶一个!!!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马