精华内容
下载资源
问答
  • picasso
    2020-07-28 12:35:14

    1.简介

    github链接
    实现图片加载功能的第三方图片加载库,需要添加依赖

    implementation 'com.squareup.picasso:picasso:2.71828'
    

    1.1 功能特性

    1. 使用默认的内存缓存和磁盘缓存(可自定义)
    2. 可自定义图片的变换操作、解析格式等
    3. 可以选择裁剪方式、大小等
    4. 可以加载网络资源、本地资源等
    5. 可以选择内存缓存和磁盘缓存的策略
    6. 可以暂停、恢复、取消加载
    7. 可以设置加载成功失败的占位图及相应监听

    1.2 使用方式

    Picasso.with(context)//拿到Picasso对象
    				.load(url)//load一个url
                    .resize(width, height)//重新裁剪大小
                    .memoryPolicy(MemoryPolicy.NO_STORE)//内存缓存策略(不存入内存)
    				.networkPolicy(NetworkPolicy.OFFLINE)//磁盘缓存策略(不通过网络请求)
                    .into(imageView);//显示到ImageView中
    

    2. 源码解析

    2.1 Picasso对象

    public static Picasso with(Content context) {
         if (singleton == null) {
              synchronized (Picasso.class) {
                   if (singleton == null) {
                        singleton = new Builder().build();
                   }
              }
         }
         return singleton;
    }
    

    Picasso使用的是单例模式,并且使用Builder模式创建了一个Picasso的实例。有了实例之后,直接调用它的load函数,Picasso重载了几个不同参数的load函数,用以从不同的地点来加载图片

    public RequestCreator load(Uri uri) {
        ...
    }
    public RequestCreator load(String path) {
        ...
    }
    public RequestCreator load(int resourceId) {
        ...
    }
    

    通过load函数,我们最终得到了一个RequestCreator对象,RequestCreator对象提供了各种占位图的设置方法以及缓存策略的方法。其内部封装了一个Request.Builder对象,用于设置图片相关参数,也是通过builder模式创建;如加载的uri、resize的大小、裁剪方式等
    最后我们调用了into函数,将加载到的图片赋给一个ImageView控件:

    public void into(Target target) {
        long started = System.nanoTime();
        checkMain();
    
        if (target == null) {
            throw new IllegalArgumentException("Target must not be null.");
        }
        if (deferred) {
            throw new IllegalStateException("Fit cannot be used with a Target.");
        }
    
        if (!data.hasImage()) {
            picasso.cancelRequest(target);
            target.onPrepareLoad(setPlaceholder ? getPlaceholderDrawable() : null);
            return;
        }
    
        Request request = createRequest(started);
        String requestKey = createKey(request);
    
        if (shouldReadFromMemoryCache(memoryPolicy)) {
            Bitmap bitmap = picasso.quickMemoryCacheCheck(requestKey);
            if (bitmap != null) {
                picasso.cancelRequest(target);
                target.onBitmapLoaded(bitmap, MEMORY);
                return;
            }
        }
    
        target.onPrepareLoad(setPlaceholder ? getPlaceholderDrawable() : null);
    
        Action action =
            new TargetAction(picasso, target, request, memoryPolicy, networkPolicy, errorDrawable,
                requestKey, tag, errorResId);
        picasso.enqueueAndSubmit(action);
    }
    
    1. into会检查当前是否是在主线程上执行。
    2. 如果我们没有提供一个图片资源并且有设置placeholder,那么就会把我们设置的placeholder显示出来,并中断执行。
    3. defered属性我们一般情况下不需要关注,只有当我们调用了RequestCreator的fit方法时defered才为true,但我们几乎不会这样做。
    4. 接下来就是创建了一个Request对象,我们在前面做得一些设置都会被封装到这个Request对象里面。
    5. 检查我们要显示的图片是否可以直接在缓存中获取,如果有就直接显示出来好了。
    6. 缓存没命中,那就只能费点事把源图片down下来了。这个过程是异步的,并且通过一个Action来完成请求前后的衔接工作。

    至此,Picasso在主线程中的工作就结束了:首先通过Picasso创建了一个RequestCreator对象,通过这个对象我们可以针对不同的场景来设置一些属性,之后创建出Request对象,最后通过Action来确定异步请求并对请求结果做处理。

    2.2 build方法

    public Picasso build() {
          Context context = this.context;
    
          if (downloader == null) {
            downloader = Utils.createDefaultDownloader(context);
          }
          if (cache == null) {
            cache = new LruCache(context);
          }
          if (service == null) {
            service = new PicassoExecutorService();
          }
          if (transformer == null) {
            transformer = RequestTransformer.IDENTITY;
          }
          Stats stats = new Stats(cache);
          Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats);
          return new Picasso(context, dispatcher, cache, listener, transformer, requestHandlers, stats,defaultBitmapConfig, indicatorsEnabled, loggingEnabled);
    }
    
    • Downloader:它是一个接口,规定了一些通用的方法,所以可以提供自己的下载器,只要实现这个接口即可,Picasso默认使用OkHttpClient来作为下载器
    • Cache:Picasso的缓存,这里实例化的是LruCache,其内部使用的是LinkedHashMap
    • ExecutorService:这里Picasso实现了自己的PicassoExecutorService,它继承了ThreadPoolExecutor,也就是Picasso自己维护了一个线程池,用于异步加载图片。
    • RequestTransformer:主要是对RequestCreator创建的Request进行转换,默认对Request对象不做处理。
    • Stats:这个类只要是维护图片的一些状态
    • Dispatcher:调度器的作用,图片要不要开始下载以及下载后Bitmap的返回都是通过这个调度器来执行的

    2.3 Dispatcher对象

    1. 内部会创建新的线程及其handler,即任何的派发、调度的请求都会在这个新的线程的handler上进行
    2. 创建时会保存住主线程的handler,在结束加载后,将结果返回到主线程上进行
    3. 在发起加载请求时,找到相应处理的RequestHandle,构建BitmapHunter对象,并将其放入到ExecutorService线程池进行执行

    RequestCreator在into方法的最后会创建一个Action实例,然后调用PicassoenqueueAndSubmit方法,而最终是调用了DispatcherdispatchSubmit方法。在Dispatcher内部,Dispatcher定义了DispatcherThreadDispatcherHandler两个内部类,并在Dispatcher的构造函数中对他们经行了实例化,所有的调度也都是通过handler异步的执行的,handler最终调用performSubmit方法来触发一个图片的加载,在这个方法中主要是获取BitmapHunter实例,由这个实例来执行实际的下载操作。BitmapHunter本身是Runnable的一个实现,而这个实例最终是交由Picasso线程池进行运行的。加载完成或失败时,还是通过Dispatcher调度器实现UI更新操作,最终会执行performComplete方法。这个方法会自动处理图片的缓存问题

    dispatcher.dispatchComplete(this)
    
    void dispatchComplete(BitmapHunter hunter) {
        handler.sendMessage(handler.obtainMessage(HUNTER_COMPLETE, hunter));
    }
    
    public void handleMessage(final Message msg) {
          switch (msg.what) {
            ...
            case HUNTER_COMPLETE: {
              BitmapHunter hunter = (BitmapHunter) msg.obj;
              dispatcher.performComplete(hunter);
              break;
            }
            ...
          }
    }
    
    void performComplete(BitmapHunter hunter) {
        if (shouldWriteToMemoryCache(hunter.getMemoryPolicy())) {
          cache.set(hunter.getKey(), hunter.getResult());
        }
        hunterMap.remove(hunter.getKey());
        batch(hunter);
        if (hunter.getPicasso().loggingEnabled) {
          log(OWNER_DISPATCHER, VERB_BATCHED, getLogIdsForHunter(hunter), "for completion");
        }
    }
    

    这个时候,Picasso并不是立即将图片显示出来,而是用到了一个批处理,其实就是把操作先暂存在一个list中,等空闲的时候再拿出来处理,这样做得好处也是尽量减少主线程的执行时间,一方面防止ANR,另一方面快速返回,响应页面的其他渲染操作,防止卡顿用户界面。

    private void batch(BitmapHunter hunter) {
        if (hunter.isCancelled()) {
          return;
        }
        batch.add(hunter);
        if (!handler.hasMessages(HUNTER_DELAY_NEXT_BATCH)) {
          handler.sendEmptyMessageDelayed(HUNTER_DELAY_NEXT_BATCH, BATCH_DELAY);
        }
    }
    
    public void handleMessage(final Message msg) {
          switch (msg.what) {
            ...
            case HUNTER_DELAY_NEXT_BATCH: {
              dispatcher.performBatchComplete();
              break;
            }
            ...
          }
    }
    

    最后还是调用了Dispatcher的方法来处理,但由于这个处理并非是在主线程,因此还需要通过一个主线程的Handler来处理这个请求

    void performBatchComplete() {
        List<BitmapHunter> copy = new ArrayList<BitmapHunter>(batch);
        batch.clear();
        mainThreadHandler.sendMessage(mainThreadHandler.obtainMessage(HUNTER_BATCH_COMPLETE, copy));
        logBatch(copy);
    }
    

    这个mainThreadHandler是在Dispatcher实例化时由外部传递进来的,Picasso在通过Builder创建时会对Dispatcher进行实例化,在那个地方将主线程的handler传了进来,回到Picasso这个类,看到其有一个静态成员变量HANDLER。

    static final Handler HANDLER = new Handler(Looper.getMainLooper()) {
        @Override public void handleMessage(Message msg) {
          switch (msg.what) {
            case HUNTER_BATCH_COMPLETE: {
              @SuppressWarnings("unchecked") List<BitmapHunter> batch = (List<BitmapHunter>) msg.obj;
              //noinspection ForLoopReplaceableByForEach
              for (int i = 0, n = batch.size(); i < n; i++) {
                BitmapHunter hunter = batch.get(i);
                hunter.picasso.complete(hunter);
              }
              break;
            }
            ...
          }
        }
    };
    

    Picasso中一个Action提供了请求前后的衔接工作,对于现在的情况,Picasso使用了ImageViewAction来进行处理,也就是在ImageViewAction中的complete方法完成了最后的图片渲染工作。

    public void complete(Bitmap result, Picasso.LoadedFrom from) {
        if (result == null) {
          throw new AssertionError(
              String.format("Attempted to complete action with no result!\n%s", this));
        }
    
        ImageView target = this.target.get();
        if (target == null) {
          return;
        }
    
        Context context = picasso.context;
        boolean indicatorsEnabled = picasso.indicatorsEnabled;
        PicassoDrawable.setBitmap(target, context, result, from, noFade, indicatorsEnabled);
    
        if (callback != null) {
          callback.onSuccess();
        }
    }
    

    学习借鉴链接 Android Picasso 原理解析
    android中的三级缓存

    更多相关内容
  • picasso

    2021-03-13 08:25:22
    picasso
  • Picasso是Square公司开源的一个Android图形缓存库。可以实现图片下载和缓存功能。 二、Picasso的特性 Picasso是一个Android图片加载缓存框架,它具有如下特性:  1.支持任务优先级,会优先加载“优先级”较高的...
  • picasso:https

    2021-05-04 11:49:19
    毕加索强大的Android图片下载和缓存库 欲了解更多信息,请下载下载或通过Gradle获取: compile ' com.squareup.picasso:picasso:2.5.2 ' 或Maven: < dependency> < groupId>com.squareup.picasso</ groupId> ...
  • 看到了这里,相信大家对Picasso的使用已经比较熟悉了,本篇博客中将从基本的用法着手,逐步的深入了解其设计原理。 Picasso的代码量在众多的开源框架中算得上非常少的一个了,一共只有35个class文件,但是麻雀虽小,...
  • 毕加索一个强大的安卓图片下载和缓存库 欲了解更多信息,请参阅下载下载或通过 Gradle 抓取: compile ' com.squareup.picasso:picasso:2.3.4 ' 或 Maven: < dependency> < groupId>com.squareup.picasso</ groupId...
  • 这篇文章中我们来继续学习Picasso中还提供了哪些扩展功能,一个好的框架一定是扩展性强的,你需要的我刚好有。 下面看一下都提供了哪些扩展功能呢? Picasso内部采用了建造者模式,所以我们只看Builder内部类都提供...
  • Picasso2.7

    2018-07-27 16:51:24
    由于Picasso通过provider获取Context所以需要在AndroidManifest.xml添加如下provider android:name="com.squareup.picasso.PicassoProvider" android:authorities="<自己的包名>.com.squareup.picasso" android:...
  • Picasso允许在您的应用程序中轻松加载图像-通常只需一行代码! 毕加索会自动处理Android上许多常见的图像加载陷阱:处理ImageView回收和适配器中的下载取消。 复杂的图像转换,使用最少的内存。 自动内存和磁盘缓存...
  • Picasso是58同城推出的一款sketch设计稿智能解析工具,可将sketch设计稿自动解析成还原精准,可用度高的前端代码。 Picasso A tool automatically convert sketch to code. 简介 Picasso是58同城推出的一款...
  • 毕加索强大的Android图片下载和缓存库 有关更多信息,请下载从下载最新的AAR或通过Gradle获取: implementation ' com.squareup.picasso:picasso:2.71828 ' 或Maven: < dependency> < groupId>com.squareup.picasso...
  • picasso 图片处理工具类 优缺点:对图片处理强大,取消已经不在视野范围的ImageView图片资源的加载(否则会导致图片错位), 使用4.0+系统上的HTTP缓存来代替磁盘缓存;只能得到结果,不能监听图片下载过程
  • picasso-2.8.0.aar

    2021-07-02 10:26:42
    Android 的图片下载框架 替换 为androix 库 可以支持 android studio 4.1 以上的ide 开发
  • 毕加索 一款sketch插件,可将sketch设计稿页面自动解析成前端代码。 简介 是58个同城推出的一个素描设计稿解析插件,可将素描设计稿自动解析成还原精确,可用度高的开头代码。 最早 草图> = 60 使用 注:安装picasso...
  • 本篇文章主要介绍了Android Picasso使用高斯模糊处理的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 教程名称: 尚硅谷Android视频《Picasso》 Picasso是Square公司出品的一个强大的图片下载和缓存图片库。本视频详细了Picasso框架的核心功能包括且不仅限于:基本方法加载图片、在listview中加载图片和36种转换的...
  • Android Picasso实现圆形图片和圆角图片
  • 主要为大家详细介绍了Android图片加载利器之Picasso的基本用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 毕加索变换 一个Android转换库,为提供了各种图像转换。 请随时使用。您是否正在使用Glide或Fresco?演示版原始图片转变如何使用?步骤1Gradlerepositories { jcenter()}dependencies { compile ' jp.wasabeef:...
  • Picasso下载网络图片.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 在做android图片加载的时候,由于手机屏幕受限,很多大图加载过来的时候,我们要求等比例缩放,接下来小编给大家带来了Android 使用Picasso加载网络图片等比例缩放的实现方法,感兴趣的朋友一起看看吧
  • 毕加索缓存 Picasso 的内存缓存。 我们可以通过这个自定义内存缓存。 用 // Loading pic. PicassoCache.getPicasso() .load("http://www.google.com/images/srpr/logo11w.png") .into(imageView); // Clear ...
  • Picasso简单封装

    2016-12-29 23:36:05
    1.Picasso的工具类PicassoUtils 这个类使用单例设计模式,全局使用一个,也就是全局使用一个Picasso对象,在Demo中我是在基类(BaseActivity)中初始化的;在PicassoUtils这个类中封装了一些加载图片的方法,加载...
  • 一个示例项目,展示了如何使用 Picasso Android 库下载和显示用作 Base64 字符串的图像。 整个想法是基于使用自定义毕加索实例和自定义下载实现。 笔记 Anroid 应用程序未实现任何缓存机制(内存或磁盘),因此...
  • 语言:English (United States) 浏览器选项卡中的艺术杰作。... picasso用各种艺术杰作替换了Chrome的默认新标签页,每天向您展示一幅新的绘画。 单击后台以获取有关艺术品的信息或跳到下一个。 图像由Wikiart提供。
  • 结合Picasso实现很炫的图片效果框架 开源项目地址:https://github.com/open-android/Picasso-transformations PS:如果觉得文章太长,你也可观看该课程的视频,亲,里面还有高清,无码的福利喔 运行效果   爱生活,...
  • 入门正在安装npm install picasso.js用法import picasso from 'picasso.js' ;picasso . chart ( { element : document . querySelector ( '#container' ) , // container must have a width and height specified ...
  • Picasso的简单使用

    2019-01-20 00:26:24
    Picasso图片加载框架,方便快捷,是一款很好用的图片加载框架。
  • 主要介绍了Andorid开发之Picasso通过URL获取用户头像的圆形显示,非常不错,具有参考借鉴价值,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,739
精华内容 7,895
关键字:

picasso