0 说明

现在Android开源库中有许多图片加载框架,本文以picasso为例,总结下开发过程中的一些优化经验,使用的picasso版本如下

compile 'com.squareup.picasso:picasso:2.5.2'

1 图片裁剪

在列表页尽量使用裁剪后的图片,在查看大图模式下才加载完整的图片。

图片裁剪示例

Picasso.with( imageView.getContext() )
.load(url)
.resize(dp2px(250),dp2px(250))
.centerCrop()
.into(imageView);

picasso默认情况下会使用全局的ApplicationContext,即开发者传进去Activity,picasso也会通过activity获取ApplicationContext。

2 查看大图放弃memory cache

Picasso默认会使用设备的15%的内存作为内存图片缓存,且现有的api无法清空内存缓存。我们可以在查看大图时放弃使用内存缓存,图片从网络下载完成后会缓存到磁盘中,加载会从磁盘中加载,这样可以加速内存的回收。

Picasso.with(getApplication())
.load(mURL)
.memoryPolicy(NO_CACHE, NO_STORE)
.into(imageView);

其中memoryPolicy的NO_CACHE是指图片加载时放弃在内存缓存中查找,NO_STORE是指图片加载完不缓存在内存中。

3 RecyclableImageView

重写ImageView的onDetachedFromWindow方法,在它从屏幕中消失时回调,去掉drawable引用,能加快内存的回收。

public class RecyclerImageView extends ImageView
{
... @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setImageDrawable(null);
}
}

实验环境:加载大图不使用内存缓存。

实验场景:从图片列表页切换到详情页看大图,然后返回,不停重复。

普通ImageView

RecyclableImageView

可以看到使用了RecyclableImageView的实验在切换过程中产生的内存谷值明显优于ImageView,说明drawable更容易被回收。

4 新进程中查看大图

列表页的内存已经非常稳定,但是查看大图时,大图往往占用了20+m内存,加上现有进程中的内存,非常容易oom,在新进程中打开Activity成为比较取巧的避免oom的方式。

<activity android:name=".DetailActivity" android:process=":picture"/>

只要在AndroidManifest.xml中定义Activity时加入process属性,即可在新进程中打开此Activity。由此,picasso也将在新进程中创建基于新ApplicationContext的单例。

5 列表页滑动优化

picasso可以对多个加载请求设置相同的tag,即

Object tag = new Object();
Picasso.with( imageView.getContext() )
.load(url)
.resize(dp2px(250),dp2px(250))
.centerCrop()
.tag(tag)
.into(imageView);

例如在RecyclerView滑动时监听,处理不同的表现:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
Picasso.with(context).resumeTag(tag);
}
else
{
Picasso.with(context).pauseTag(tag);
}
}
});

6 RGB_565

对于不透明的图片可以使用RGB_565来优化内存。

Picasso.with( imageView.getContext() )
.load(url)
.config(Bitmap.Config.RGB_565)
.into(imageView);

默认情况下,Android使用ARGB_8888

Android中有四种,分别是:
ALPHA_8:每个像素占用1byte内存
ARGB_4444:每个像素占用2byte内存
ARGB_8888:每个像素占用4byte内存
RGB_565:每个像素占用2byte内存

RGB_565呈现结果与ARGB_8888接近,内存对比如下图

默认ARGB_8888,列表滑动时平均内存10m

RGB_565,列表滑动时,平均7M

7 reference

Picasso and Context

JakeWharton的避免OOM建议

Clear Cache mem

原文链接:http://www.jianshu.com/p/6b746c904a49

Picasso使用的方法汇总:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
Picasso.with(context).load(url).into(view);
Picasso.with(context).load(url) .resize(50, 50).centerCrop().into(imageView)
//这里的placeholder将resource传入通过getResource.getDrawable取资源,所以可以是张图片也可以是color id
Picasso.with(context).load(url).placeholder(R.drawable.user_placeholder).error(R.drawable.user_placeholder_error).into(imageView);

Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
//这里显示notification的图片
Picasso.with(activity).load(Data.URLS[new Random().nextInt(Data.URLS.length)]).resizeDimen(R.dimen.notification_icon_width_height,
   R.dimen.notification_icon_width_height).into(remoteViews, R.id.photo, NOTIFICATION_ID, notification);
//这里是通过设置tag标签,就是当前传过来的context,这样就可以根据这个context tag来pause和resume显示了
Picasso.with(context).load(url).placeholder(R.drawable.placeholder).error(R.drawable.error).fit().tag(context).into(view);
//监听onScrollStateChanged的时候调用执行
picasso.resumeTag(context);
picasso.pauseTag(context);

Picasso.with(context).load(contactUri).placeholder(R.drawable.contact_picture_placeholder).tag(context).into(holder.icon);
//这个onpause方法里的这段代码还是很有意思的
@Override protected void onPause() {
    super.onPause();
    if (isFinishing()) {
      // Always cancel the request here, this is safe to call even if the image has been loaded.
      // This ensures that the anonymous callback we have does not prevent the activity from
      // being garbage collected. It also prevents our callback from getting invoked even after the
      // activity has finished.
      Picasso.with(this).cancelRequest(imageView);
    }
  }
// Trigger the download of the URL asynchronously into the image view.
    Picasso.with(context)
        .load(url)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error)
        .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
        .centerInside()
        .tag(context)
        .into(holder.image);
//Picasso.with使用的是单例模式
Picasso.with(this).cancelTag(this);

然后呢,Picasso还提供了debug的标示,调用picasso的setIndicatorsEnabled方法,true是debug模式,跟踪代码其实就是在最后生成的PicassoDrawable类的ondraw里绘制了个左上角小三角,根据

public enum LoadedFrom {

    MEMORY(Color.GREEN),

    DISK(Color.BLUE),

    NETWORK(Color.RED);

枚举里的不同值标示不同加载来源,这对分析图片加载有好处。

另外链接个分析picasso源码不错的博客地址http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0731/1639.html

不要感谢我哦!

Picasso真心是个很强大的图片加载框架,之前用过universal-Image-Loader图片加载框架也挺不错的

开源的力量很强大啊☻

Android框架 加载图片 库 Picasso 的使用简介的更多相关文章

  1. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果

     Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...

  2. 【转载】cocos2dx 中 Android NDK 加载动态库的问题

     原文地址:http://blog.csdn.net/sozell/article/details/10551309 cocos2dx 中 Android NDK 加载动态库的问题 闲聊 最近在接入各 ...

  3. 演化理解 Android 异步加载图片(转)

    演化理解 Android 异步加载图片(转)http://www.cnblogs.com/CJzhang/archive/2011/10/20/2218474.html

  4. [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html  这个可以实现ImageView异步加载 ...

  5. Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处http://blog.csdn.net/xiaanming/article/details ...

  6. android 网络加载图片,对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存

    经常会用到 网络文件 比如查看大图片数据 资源优化的问题,当然用开源的项目  Android-Universal-Image-Loader  或者 ignition 都是个很好的选择. 在这里把原来 ...

  7. 实例演示Android异步加载图片

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  8. 实例演示Android异步加载图片(转)

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  9. 演化理解 Android 异步加载图片

    原文:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html#3018499 在学习"Android异步加载图像小结&q ...

随机推荐

  1. [Hibernate] - mysql

    Hibernate使用mysql例子: 1) 新建一个bean: User.java package com.my.bean; import java.util.Date; public class ...

  2. 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  3. C# 用正则表达式替换字符串中所有特殊字符

    descriptionXML = Regex.Replace(ToDBC(descriptionXML.ToUpper().Replace((char)32, ' ').Replace((char)1 ...

  4. elasticsearch2

    简单认为是可以在命令行下访问url的一个工具 curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求. curl -x 指定http请求的方法 ...

  5. PLSQL_基础系列02_分组函数GROUP BY / ROLLUP / CUBE(案例)

    2014-11-30 Created By BaoXinjian

  6. POJ 1185 炮兵阵地(状态压缩DP)

    题解:nState为状态数,state数组为可能的状态 代码: #include <map> #include <set> #include <list> #inc ...

  7. Linux命令(15)查看系统版本信息

    一,查看Linux内核版本命令(两种方法) 1.cat /proc/version [user@fgejjw7Z home]$ cat /proc/version Linux version -.el ...

  8. 简单且线程安全的两个单例模式java程序

    /***具体说明见 http://www.cnblogs.com/coffee/archive/2011/12/05/inside-java-singleton.html*/ package com. ...

  9. Eclipse中generate getter and setter对boolean的反应

    有点意思 , 如果变量是boolean类型的  ,就会生成isxxx开头的getter方法 , 但如果是Boolean对象的 , 就会生成getterxx开头的getter对象. 例如 Boolean ...

  10. bat命令之for命令详解

    ______________版主提醒____________________________ 为了避免影响技术讨论.提高看帖的舒适性,请大家不要在此帖下跟无实质内容的口水帖,特别是纯顶.纯支持.纯感谢 ...