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. 解决关于jquery中$.get()方法总是报“HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy”错的方法

    解决关于jquery中$.get()方法总是报“HierarchyRequestError: Node cannot be inserted at the specified point in the ...

  2. 异步I/O编程实例,异步socket

    下载地址: http://files.cnblogs.com/badnewfish/RUYEESocket.rar ———————————————————————————————————————— 举 ...

  3. 剑指offer系列37----数据流中的中位数

    [题目]如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值, * 那么中位数就是所有数值排序之后位于中间的数值. package com.exe8.offer; import java.uti ...

  4. oracle学习笔记(二)设置归档模式

    设置归档模式(mount状态) ALTER database ARCHIVELOG; //关闭数据库 shutdown immediate //启动数据库到mount状态 startup mount ...

  5. 99. Recover Binary Search Tre

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  6. 《黄聪:手机移动站SEO优化教程》1、为什么要做手机移动端网站

    视频地址:http://v.youku.com/v_show/id_XNzE2Mzk3MjI4.html

  7. BIP_开发案例05_BI Pubisher标准做法以BIP.XML为数据源以BIP.RTF为模板的简单例子(案例)

    2014-05-31 Created By BaoXinjian

  8. python(21)实现多进程

    参考链接:http://www.cnblogs.com/kaituorensheng/p/4445418.html python多进程:multiprocessing python中的多线程其实并不是 ...

  9. 张恭庆编《泛函分析讲义》第二章第2节 $Riesz$ 定理及其应用习题解答

    在本节中, $\scrH$ 均指 $Hilbert$ 空间. 1.在极大闭子空间的交的最佳逼近元 设 $f_1,f_2,\cdots,f_n$ 是 $\scrH$ 上的一组线性有界泛函, $$\bex ...

  10. 启动mongoDB 以及常用操作命令

    nonsql    关系数据库 集合  表 文档 行 启动mongoDB之前首先手动创建存放MongoDB数据文件的目录,如e:\mongo_data 执行命令  mongod --dbpath=e: ...