Picasso的使用和源码解析

Picasso的简单使用 Picasso图片加载框架,方便快捷,是一款很好用的图片加载框架。 立即下载

一、基本介绍

picasso是Square公司开源的一个Android图片下载缓存库,github地址https://github.com/square/picasso,可以实现图片下载和缓存功能。

Picassso的特点有:

自动将图像缓存在本地,自带内存和硬盘二级缓存功能
通过图片压缩转换以减少内存消耗
自动处理了ImageView的回收,自动取消不在视野范围内的ImageView视图资源的加载

支持网络图片,drawable资源,asset资源,本地图片等多种资源加载

支持调试,调用函数 Picasso.setIndicatorsEnabled(true) 可以在加载的图片左上角显示一个三角形,,不同的颜色代表不同的加载来源。

二、使用方法

1、gradle 配置

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

2、普通图片加载方式

只需要一行代码就能完全实现图片的异步加载:

Picasso.with(context).load("https://img-my.youkuaiyun.com/uploads/201605/08/1462674108_9582.jpg").into(imageView);

3、ADAPTER 中加载图片:Adapter的重用会被自动检测到,Picasso会取消上次的加载

@Override 
public void getView(int position, View convertView, ViewGroup parent) {
  Imageview view = (ImageView) convertView;
  if (view == null) {
    view = new ImageView(context);
  }
  String url = getItem(position);
  Picasso.with(context).load(url).into(view);
}

 4、图片转换:转换图片以适应布局大小并减少内存占用

 Picasso.with(context)
  .load(url)
  .resize(50, 50)
  .centerCrop()
  .into(imageView);

5、Place holders-空白或者错误占位图片:

picasso提供了两种占位图片,未加载完成或者加载发生错误的时需要一张图片作为提示。

Picasso.with(context)
  .load(url)
  .placeholder(R.drawable.placeholder)
  .error(R.drawable.placeholder_error)
.into(imageView);

6、多种资源文件的加载:

除了加载网络图片picasso还支持加载Resources, assets, files, content providers中的资源文件。

Picasso.with(context).load(R.drawable.landing_screen).into(imageview);
Picasso.with(context).load(new File(...)).into(imageview);
Picasso.with(context).load("file:///android_asset/robert.png").into(imageview);

三、源码解析

1、构建方式

Picasso使用Builder创建对象,我们一般使用public static Picasso with(Context context)方法

public static Picasso with(Context context) {
     if (singleton == null) {
         synchronized (Picasso.class) {
             if (singleton == null) {
                 singleton = new Builder(context).build();
             }
         }
     }
     return singleton;
 }
Picasso的with方法返回Picasso的单例,但是有Builderg构造器,Picasso不是严格意义上的单例模式。
多次build还是可以创建多个实例的。

使用build构建可以自定义线程池、缓存、下载器等方法。

2、资源加载方式

实现RequestHandler接口就可以定义资源加载方式,默认有7种

allRequestHandlers.add(new ResourceRequestHandler(context));//drawable资源图
allRequestHandlers.add(new ContactsPhotoRequestHandler(context));//通讯录图片
allRequestHandlers.add(new MediaStoreRequestHandler(context));//多么媒体资源库图片
allRequestHandlers.add(new ContentStreamRequestHandler(context));//Provider图片
allRequestHandlers.add(new AssetRequestHandler(context));//asset中的图片
allRequestHandlers.add(new FileRequestHandler(context));//存储设备中的图片
allRequestHandlers.add(new NetworkRequestHandler(dispatcher.downloader, stats));//网络图片
可以通过extraRequestHandlers添加新的支持方法,定义新的RequestHandler,需要实现两个方法
public abstract boolean canHandleRequest(Request data);
public abstract Result load(Request request, int networkPolicy) throws IOException;
canHandleRequest定义了在什么情况下用这种方式
load定义了加载具体加载方式
具体看一下NetworkRequestHandler的具体实现,相关解析直接加注释
class NetworkRequestHandler extends RequestHandler {
  static final int RETRY_COUNT = 2;//重试次数

  private static final String SCHEME_HTTP = "http";//识别的scheme
  private static final String SCHEME_HTTPS = "https";//识别的scheme

  private final Downloader downloader;//下载器
  private final Stats stats;//状态
 /**
  * 构造方法
  */
  public NetworkRequestHandler(Downloader downloader, Stats stats) {
    this.downloader = downloader;
    this.stats = stats;
  }

  @Override public boolean canHandleRequest(Request data) {
    String scheme = data.uri.getScheme();
    return (SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme));
  }

  @Override public Result load(Request request, int networkPolicy) throws IOException {
    Response response = downloader.load(request.uri, request.networkPolicy);
    if (response == null) {
      return null;
    }
    Picasso.LoadedFrom loadedFrom = response.cached ? DISK : NETWORK;
    Bitmap bitmap = response.getBitmap();
    if (bitmap != null) {
      return new Result(bitmap, loadedFrom);
    }

    InputStream is = response.getInputStream();
    if (is == null) {
      return null;
    }
    // Sometimes response content length is zero when requests are being replayed. Haven't found
    // root cause to this but retrying the request seems safe to do so.
    if (loadedFrom == DISK && response.getContentLength() == 0) {
      Utils.closeQuietly(is);
      throw new ContentLengthException("Received response with 0 content-length header.");
    }
    if (loadedFrom == NETWORK && response.getContentLength() > 0) {
      stats.dispatchDownloadFinished(response.getContentLength());
    }
    return new Result(is, loadedFrom);
  }

  @Override int getRetryCount() {
    return RETRY_COUNT;
  }

  @Override boolean shouldRetry(boolean airplaneMode, NetworkInfo info) {
    return info == null || info.isConnected();
  }

  @Override boolean supportsReplay() {
    return true;
  }
  static class ContentLengthException extends IOException {
    public ContentLengthException(String message) {
      super(message);
    }
  }
}

3、请求创建器RequestCreator

Picasso的load方法返回RequestCreator,RequestCreator有两个功能
配置加载参数。
包括placeHolder与error图片,加载图片的大小、旋转、居中等属性。
执行加载。
通过调用into(object)方法进行加载。

 public RequestCreator load(String path) {
        if (path == null) {
            return new RequestCreator(this, null, 0);
        }
        if (path.trim().length() == 0) {
            throw new IllegalArgumentException("Path must not be empty.");
        }
        return load(Uri.parse(path));
    }
into方法只能在主线程调用,否则会抛出异常。如果没有要加载的资源,请求会被取消,提高了执行效率

static void checkMain() {
  if (!isMain()) {
    throw new IllegalStateException("Method call should happen from the main thread.");
      }
}
取消操作是Picasso的方法,也只能在主线程调用

/**
 * Cancel any existing requests for the specified target {@link ImageView}.
 */
public void cancelRequest(ImageView view) {
    // checkMain() is called from cancelExistingRequest()
    if (view == null) {
        throw new IllegalArgumentException("view cannot be null.");
    }
    cancelExistingRequest(view);
}

如果target不为空,执行线程正常,就可以正常构建request,创建requestkey,requestkey使用简单的属性拼接方法
如果设置了内存缓存,那么从内存缓存中读取图片,图片不为空,直接设置图片。
如果没有设置缓存,或者从缓存中读取到的图片为空,那么创建图片获取任务,

4、执行任务Action

Action是一个抽象类,可以理解为一个加载任务,
FetchAction 缓存图片
RemoteViewsAction 给RemoteView设置图片
GetAction 同步获取图片
ImageViewAction 给ImageView设置图片

TargetAction 对Target设置图片

调用RequestCreator对应方法会对应创建所需要的Action

public void into(Target target)
public void fetch() 
public Bitmap get() throws IOException
public void into(ImageView target)
public void into(RemoteViews remoteViews, int viewId, int notificationId,Notification notification) 

需要特别注意的是 public Bitmap get() throws IOException 是同步方法,其他几个是异步方法

异步方法将Action提交到Dispatcher,同步方法直接使用BitmapHunter获取图片

获取完图片,处理图片的方法是

  abstract void complete(Bitmap result, Picasso.LoadedFrom from);
不同子类对应不同实现

5、事件分发器

默认的Dispatcher创建方法

Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats);

context参数就不用多说了,service是Pecasso的异步线程池,HANDLER用来向主线程抛消息,downloader是下载器

cache是图片缓存,stats是执行状态

Dispatcher是分发器,由Picasso或Hunter来调用。Dispatcher主要方法有
dispatcherSubmit()和dispatcherCancel()
hunter中加入action便调用dispatcherSubmit(),hunter中取消action便调用dispatcherCancel()
dispatcherComplete()和dispatcherError()
加载结束时调用。均调用batch方法,不过complete操作会将bitmap加入到cache中,以便后续调用。
batch()
起缓冲作用,每隔200毫秒执行一次performBatchComplete()批处理。批处理将hunterList回调给Picasso,Picasso对每个hunter的每个action进行结果回调。

Dispatcher启动了自己的线程dispatcherThread。DispatcherHandler运行在DispatcherThread中。

RequestCreator中调用了Picasso的submit方法,将acton提交到Dispatcher,
DispatcherHandler发送了REQUEST_SUBMIT这个消息,然后在DispatcherHandler所在线程中执行了performSubmit,
在performSubmit中创建BitmapHunter,进行下载。

  void performSubmit(Action action, boolean dismissFailed) {
    if (pausedTags.contains(action.getTag())) {
      pausedActions.put(action.getTarget(), action);
      if (action.getPicasso().loggingEnabled) {
        log(OWNER_DISPATCHER, VERB_PAUSED, action.request.logId(),
            "because tag '" + action.getTag() + "' is paused");
      }
      return;
    }

    BitmapHunter hunter = hunterMap.get(action.getKey());
    if (hunter != null) {
      hunter.attach(action);
      return;
    }

    if (service.isShutdown()) {
      if (action.getPicasso().loggingEnabled) {
        log(OWNER_DISPATCHER, VERB_IGNORED, action.request.logId(), "because shut down");
      }
      return;
    }

    hunter = forRequest(action.getPicasso(), this, cache, stats, action);
    hunter.future = service.submit(hunter);
    hunterMap.put(action.getKey(), hunter);
    if (dismissFailed) {
      failedActions.remove(action.getTarget());
    }

    if (action.getPicasso().loggingEnabled) {
      log(OWNER_DISPATCHER, VERB_ENQUEUED, action.request.logId());
    }
  }


6、图片获取BitmapHunter

BitmapHunter是一个Runnable,作用是获取图片。
BitmapHunter的执行流程:在run()方法中执行hunt()方法尝试获取图片,把结果交给Dispatcher回调。

  Bitmap hunt() throws IOException {
    Bitmap bitmap = null;

    if (shouldReadFromMemoryCache(memoryPolicy)) {
      bitmap = cache.get(key);
      if (bitmap != null) {
        stats.dispatchCacheHit();
        loadedFrom = MEMORY;
        if (picasso.loggingEnabled) {
          log(OWNER_HUNTER, VERB_DECODED, data.logId(), "from cache");
        }
        return bitmap;
      }
    }

    data.networkPolicy = retryCount == 0 ? NetworkPolicy.OFFLINE.index : networkPolicy;
    RequestHandler.Result result = requestHandler.load(data, networkPolicy);
    if (result != null) {
      loadedFrom = result.getLoadedFrom();
      exifOrientation = result.getExifOrientation();
      bitmap = result.getBitmap();
      ........
    }

    if (bitmap != null) {
      if (picasso.loggingEnabled) {
        log(OWNER_HUNTER, VERB_DECODED, data.logId());
      }
      stats.dispatchBitmapDecoded(bitmap);
      if (data.needsTransformation() || exifOrientation != 0) {
        synchronized (DECODE_LOCK) {
          if (data.needsMatrixTransform() || exifOrientation != 0) {
            bitmap = transformResult(data, bitmap, exifOrientation);
            if (picasso.loggingEnabled) {
              log(OWNER_HUNTER, VERB_TRANSFORMED, data.logId());
            }
          }
          if (data.hasCustomTransformations()) {
            bitmap = applyCustomTransformations(data.transformations, bitmap);
            if (picasso.loggingEnabled) {
              log(OWNER_HUNTER, VERB_TRANSFORMED, data.logId(), "from custom transformations");
            }
          }
        }
        if (bitmap != null) {
          stats.dispatchBitmapTransformed(bitmap);
        }
      }
    }

    return bitmap;
  }

7、缓存处理

内存缓存使用LruCache,实现是在LruCache.java中,动态分配缓存大小,大小为可用内存的1/7,

磁盘缓存使用了网络框架的缓存方案。

8、网络请求处理

定义了三种下载器,分别用于okhttp3,okhttp,urlconneciton

static Downloader createDefaultDownloader(Context context) {
    if (SDK_INT >= GINGERBREAD) {
      try {
        Class.forName("okhttp3.OkHttpClient");
        return OkHttp3DownloaderCreator.create(context);
      } catch (ClassNotFoundException ignored) {
      }
      try {
        Class.forName("com.squareup.okhttp.OkHttpClient");
        return OkHttpDownloaderCreator.create(context);
      } catch (ClassNotFoundException ignored) {
      }
    }
    return new UrlConnectionDownloader(context);
  }

9、线程池优化

PicassoExecutorService根据网络状况,使用不同的线程池,命中次数多的,优先级高

    switch (info.getType()) {
      case ConnectivityManager.TYPE_WIFI:
      case ConnectivityManager.TYPE_WIMAX:
      case ConnectivityManager.TYPE_ETHERNET:
        setThreadCount(4);
        break;
      case ConnectivityManager.TYPE_MOBILE:
        switch (info.getSubtype()) {
          case TelephonyManager.NETWORK_TYPE_LTE:  // 4G
          case TelephonyManager.NETWORK_TYPE_HSPAP:
          case TelephonyManager.NETWORK_TYPE_EHRPD:
            setThreadCount(3);
            break;
          case TelephonyManager.NETWORK_TYPE_UMTS: // 3G
          case TelephonyManager.NETWORK_TYPE_CDMA:
          case TelephonyManager.NETWORK_TYPE_EVDO_0:
          case TelephonyManager.NETWORK_TYPE_EVDO_A:
          case TelephonyManager.NETWORK_TYPE_EVDO_B:
            setThreadCount(2);
            break;
          case TelephonyManager.NETWORK_TYPE_GPRS: // 2G
          case TelephonyManager.NETWORK_TYPE_EDGE:
            setThreadCount(1);
            break;
          default:
            setThreadCount(DEFAULT_THREAD_COUNT);
        }
        break;
      default:
        setThreadCount(DEFAULT_THREAD_COUNT);
    }



欢迎扫描二维码,关注公众账号


picasso 立即下载

相关推荐

Android图片加载利器之Picasso基本用法

主要为大家详细介绍了Android图片加载利器之Picasso的基本用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

源码阅读系列:Picasso源码阅读

源码阅读系列:Picasso源码阅读Picasso初始化加载图片 Android开发中,我们经常用到各种开源框架,很多优秀的框架不仅提供了功能丰富的功能接口,其高超的代码编写和组织水平也值得我们学习。通过学习这些框架的源码,有助于快速提高我们的编程质量。在接下来的博客中,我将对一系列优秀的开源框架源码进行阅读分析,目的有两个,一是理解框架的实现机制,从源码的角度去分析怎样更好的使用这些框架。二是从...

小鹿的爸爸 255

2025东方财富笔试考什么?cata能力测评攻略|答题技巧真题分享

4月10日-4月20日 专业笔试(行测+金融知识混合双打) 4月25日-5月10日 面试车轮战(AI面+半结构化+压力面) 5月15日起 Offer发放(谈薪必杀技:对标同花顺/雪球)这里不仅是金融极客的乐园,更是**“年薪30万管培生计划”**的主战场——你将用代码重构K线,用算法预判市场,成为资本市场的“数字先知”。东方财富,中国金融信息服务领域的“隐形冠军”,以**“金融数据+互联网”双擎驱动**,打造了覆盖证券、基金、期货的全生态交易平台。:• “我总坚持自己的方案”(HR:团队毒药!

Dgntsj的博客 3259

简单说说我最常用的图片加载库 Picasso

对于一个需要展示很多图片或较多图片的App来说,一个好的图片加载框架是必不可少的。在我刚开始学习Android的时候,什么都想自己写,我以前做过一个看漫画的App,里面的图片加载,缓存等都是自己写的,但是效果并不理想,当时利用了LruCache来做图片的内存缓存,用DiskLruCache做磁盘缓存,加载图片根据Key先在内存中查询,如果没有就再去磁盘中查询,若果再没有在去网络上加载。虽然是个逻...

weixin_34384915的博客 222

Transformer模型详解(图解最完整版)

Transformer由论文提出,现在是谷歌云TPU推荐的参考模型。论文相关的Tensorflow的代码可以从GitHub获取,其作为Tensor2Tensor包的一部分。哈佛的NLP团队也实现了一个基于PyTorch的版本,并注释该论文。在本文中,我们将试图把模型简化一点,并逐一介绍里面的核心概念,希望让普通读者也能轻易理解。Transformer 与 RNN 不同,可以比较好地并行训练。

2501_91695094的博客 2699

MacOS下Mixly 2.0安装避坑指南:从Java环境到终端权限全解析

本文详细解析了在MacOS系统上安装Mixly 2.0时可能遇到的核心问题与解决方案。针对Java环境版本不兼容、MacOS Gatekeeper安全机制拦截以及终端权限不足三大常见障碍,提供了从检查并配置正确Java版本、安全设置绕过到彻底解决应用内部工具链权限的完整避坑指南,帮助用户顺利完成安装并正常使用。

weixin_29231725的博客 502

Method call should happen from the main thread.

在Application加入代码关闭硬件加速即可。

Trainer2107的博客 308

从SPI协议到文件系统:手把手教你用HAL库给W25Q16移植FATFS(附扇区管理优化方案)

本文详细介绍了如何在STM32平台上,通过HAL库的SPI接口为W25Q16 Flash芯片移植FATFS文件系统。文章从SPI通信基础讲起,深入解析了FATFS底层驱动(diskio.c)的移植要点,并重点探讨了针对W25Q16的4KB物理扇区特性进行扇区管理优化的两种方案,旨在帮助开发者构建稳定高效的文件存储方案。

happy2的博客 1043

安卓:Picasso——加载网络图片的库

Picasso是一个适用于Android的强大且易于使用的图片加载和显示库。它由Square开发,并提供了许多功能和选项,以帮助开发者更轻松地处理和展示图片。Picasso提供了简洁而直观的API,使得加载和显示图片变得非常简单。只需几行代码就可以实现网络或本地图片的加载和显示。Picasso会自动处理图片的下载和缓存,无需手动管理。它会根据需要自动加载和缓存图片,并在下次请求时从缓存中获取,以提高性能和节省数据使用量。

A125679880的博客 3570

基于MATLAB的基本数字调制解调系统的设计

基于MATLAB的基本数字调制解调系统的设计一、摘要现代通信系统要求通信距离远、通信容量大、传输质量好,作为其关键技术之一的调制解调技术一直是人们研究的一个重要方向。本文以MATLAB为软件平台,充分利用其提供的通信工具箱和信号处理工具箱中的模块,对数字调制解调系统进行Simulink设计仿真,并且进行误差分析。调制与解调是通信系统中十分重要的一个环节,针对不同的信道环境选择不同的调制与解调方式可...

m0_55395440的博客 5549

Matlab实战:如何用MMG方程预测船舶轨迹(附完整代码)

本文提供了一份基于MMG方程的Matlab实战指南,详细讲解了如何从零构建船舶轨迹预测模型。内容涵盖MMG模型的核心原理、Matlab代码框架设计、动力学函数实现、参数调优与验证方法,并附有完整代码示例,帮助工程师和研究者快速掌握这一船舶操纵性预测的关键技术。

v6b7n8m9q0的博客 518

带你理解picasso

像什么Rerefoit 、OkHttp、LeakCanary、Picasso等等都是非常火的开源项目。Picasso除了使用简单方便,Picasso还能自动帮我们做以下事情: 处理Adapter 中ImageView的回收和取消下载。 使用最小的内存 来做复杂的图片变换。比如高斯模糊,圆角、圆形等处理。 自动帮我们缓存图片。内存和磁盘缓存。 添加依赖 要使用Picasso,首先我们要添加版本依赖,...

追梦赤子的博客 389

高电压技术的面试内容整理(详细版本:57题)

涵盖了高电压技术的关键领域,包括气体放电的物理过程、液体和固体介质的绝缘特性、高压外绝缘的分类与特性、电气设备绝缘试验的方法与原理、电力系统的防雷保护措施,以及内部过电压的产生、影响与限制方法,为理解和应对高电压环境下的电气问题提供了系统的知识框架。通过深入探讨气体放电理论、介质极化与损耗、绝缘子的电气特性、绝缘试验技术、防雷策略以及内部过电压的管理。

weixin_44808274的博客 775

Picasso源码完全解析(三)--Request和Action的创建

## Picasso完全源码解析(三)--Request和Action的创建## 使用Picasso可以加载链接、文件、Uri以及引用自带的res资源,     public RequestCreator load(@Nullable Uri uri) {         return new RequestCreator(this, uri, 0);     }

chenglei_56的专栏 692

【Autosar从入门到精通到进阶实战篇】75 0x34/0x36/0x37:请求下载、传输数据、请求退出——刷写流程的“三兄弟”

文章摘要:UDS刷写流程0x34/0x36/0x37关键实现要点 本文通过一个真实ECU变砖案例,揭示了UDS刷写服务(0x34请求下载、0x36传输数据、0x37请求退出)的实现陷阱与最佳实践。核心要点: 安全架构设计: 0x34阶段只协商参数,不立即擦除Flash 采用缓冲区暂存数据,避免频繁写Flash 严格检查地址对齐和内存边界 关键改进措施: 实现数据包序列号校验(防错位) 传输层缓冲区溢出保护 0x37阶段必须包含完整性校验(如CRC32) 一次性批量写入Flash,减少擦写次数 典型错误模式:

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 68

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android 图片加载框架Picasso基本使用和源码完全解析

说到Picasso,相信Android开发人员绝不陌生,它是Square公司开发的一款图片加载神器。使用过它的coder绝对是爱不释手:对它本身而言,轻量安全,有效加载图片并防止OOM;对我们开发者来说,简单方便,一行代码搞定图片加载。因此它备受Android开发人员的钟爱,那么今天我们就从源码的角度完完全全的解析下它的工作原理。

管满满 5237

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Android 图片加载框架Picasso基本使用和源码完全解析(巨细无比)

写在之前 原本打算是每周更新一篇博文,同时记录一周的生活状态,但是稍微工作忙一点就顾不上写博客了。悲催 还是说下最近的状况,最近两周一直在接公司申请的计费点, 沃商店,银贝壳,微信等等,然后就是不停的被人催促催促,真是一个头两个大。在这期间项目组还搞了个App会员登录系统,接受第三方登录,然后应用到现有的App当中,然后又是一阵狂Coding。 说道第三方登录,那必然会包含第三方用户信息,比如头像...

weixin_33921089的博客 441

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Picasso源码完全解析(六)--请求的取消、暂停、和恢复

Picasso源码完全解析(六)--请求的取消、暂停、和恢复 Picasso为管理请求,提供了取消、暂停和恢复请求的方法。 请求的取消 请求的取消通常是通过picasso.cancel方法执行的,最终会调用这个方法: private void cancelExistingRequest(Object target) { checkMain(); Action

chenglei_56的专栏 1298

Picasso源码完全解析(四)--Action分发和执行

Picasso完全源码解析(四)--Action分发和执行 上节讲到 我们的每个图片请求最后生成一个Action被提交给Picasso执行,那么那么多的Action Picasso是怎么执行的呢? void enqueueAndSubmit(Action action) { Object target = action.getTarget(); if (target !=

chenglei_56的专栏 620

Picasso源码分析

概述 前面分析了Volley的源码,现在来看一下Picasso的源码,其实Volley已经具备了加载了网络图片的功能,只是性能不是很好,Picasso是Square公司推出的一款图片加载框架,只能加载图片,所以性能肯定会比Volley好,Picasso的很多设计实际上跟Volley很相似,后来看到Picasso中的一个类BitmapHunter的注释,发现其实Picasso的作者也是参考了Vol...

狂奔的蜗牛 481

Picasso 基本方法源码分析

Picasso.with(MainActivity.this).load(url).into(iv_img); 关于Picasso Picasso其实是安卓系统的图片下载和缓存类库,是Square开源的一个用于Android系统下载和缓存图片的项目 使用方法:从官网下载Picasso.jar,直接放到libs下添加到本地库就可以了 关于with方法

qq_36571351的博客 387

Picasso从使用到源码解析

Picasso从使用到源码解析一、使用Picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能。仅仅只需要一行代码就能完全实现图片的异步加载:Picasso.with(context).load(url).into(imageView);Picasso不仅实现了图片异步加载的功能,还解决了An

高沛的博客 512

Picasso学习笔记

注:文章转载自文章转载自RowandJJ的博客:http://blog.csdn.net/chdjj/article/details/49964901 下面是我在学习Picasso过程中做的笔记.关于图片加载库的思考 我们为什么要用图片库呢? 图片库通常会对图片加载逻辑进行封装、优化,比如多级缓存/异步线程调度/图片压缩变换,有了这些特性,开发者不再需要关注内存占用、 OO

lucas的编程之旅 3182

图片加载利器之Picasso(四)源码解析

看到了这里,相信大家对Picasso的使用已经比较熟悉了,本篇博客中将从基本的用法着手,逐步的深入了解其设计原理。Picasso的代码量在众多的开源框架中算得上非常少的一个了,一共只有35个class文件,但是麻雀虽小,五脏俱全。好了下面跟随我的脚步,出发了~~~基本用法Picasso.with(this).load(imageUrl).into(imageView);with(t

landptf的博客 537
上一篇: svn,git的对比以及常用命令
下一篇: 算法系列(六)数据结构之表队列和栈
robert_chao
博客等级 码龄15年 265粉丝 119原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值