Picasso源码分析4

来源:互联网 发布:伊登软件 编辑:程序博客网 时间:2024/05/19 09:41

0使用手册

http://square.github.io/picasso/

1使用方法简介

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

2 基本原理

这里写图片描述

  1. 先使用Picasso.Builder生成一个单例Picasso,
  2. load的时候生成一个RequestCreator,再设置不同的Reqeust参数,into的时候生成一个Request,
  3. 再将Request和Target组合成Action,
  4. 由Picasso交给Dispatcher后台执行,
  5. Dispatcher用Action生成BitmapHunter,交于PicassoExecutorService执行,BitmapHunter下载完成,执行相应的变换后,
  6. 用Handler通知Dispatcher缓存在内存中,
  7. Dispatcher再用Handler通知Picasso调用Action.complete()方法

3数据结构分析

RequestHandler: 根据Request获取相应的内容。FileRequestHandler使用ContentResolver从文件中获取。NetworkRequestHandler使用Downloader从网络获取。ResourceRequestHandler从apk资源中获取。ContactsPhotoRequestHandler使用ContentResolver从通讯录中获取。ContentStreamRequestHandler使用ContentResolver获取。

Downloader: 从网络获取时需要下载。UrlConnectionDownloader使用UrlConnection从网络下载,HttpResponseCache可以让UrlConnection使用文件缓存数据。OkHttpDownloader使用OkHttp库来下载图片,OkHttpClient.setCache可以让OkHttp使用文件缓存

Stats:统计数据,缓存的命中率等等

Action:包含Request,Target和PlaceHolder,和异步加载后的回调,complete,error,cancel。

BitmapHunter: 异步Runnable任务。

4源代码分析

  1. Picasso.Builder.build()
 /** 2. 构造Picasso,使用Picasso.with会构造默认的方法,如果要自定义Picasso,则需要使用Builder,并在构造好了 3. 之后使用Picasso.setSingletonInstance.   *//** Create the {@link Picasso} instance. */    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);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  1. RequestCreator.into()
 /**     * 调用into方法时,使用Request.Builder创建一个Request,然后交给Dispatcher调度执行。     * @param target     */  public void into(Target target) {    long started = System.nanoTime();    checkMain();    if (target == null) {      throw new IllegalArgumentException("Target must not be null.");    }    //当target是ImageView时,需要deferred,生成DeferredRequestCreator,利用ImageView的addOnPreDrawListener()当需要绘制的时候再来进行加载    if (deferred) {      throw new IllegalStateException("Fit cannot be used with a Target.");    }      //url为空或者resourceid为空,直接Cancel    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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  1. BitmapHunter.hunt()
  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;      }    }      //使用RequestHandler加载图片    data.networkPolicy = retryCount == 0 ? NetworkPolicy.OFFLINE.index : networkPolicy;    RequestHandler.Result result = requestHandler.load(data, networkPolicy);    if (result != null) {      loadedFrom = result.getLoadedFrom();      exifRotation = result.getExifOrientation();      bitmap = result.getBitmap();      //如果得到的不是图片而是InputStream,则转换成Bitmap      if (bitmap == null) {        InputStream is = result.getStream();        try {          bitmap = decodeStream(is, data);        } finally {          Utils.closeQuietly(is);        }      }    }    if (bitmap != null) {      if (picasso.loggingEnabled) {        log(OWNER_HUNTER, VERB_DECODED, data.logId());      }      stats.dispatchBitmapDecoded(bitmap);        //进行裁剪,旋转等变换      if (data.needsTransformation() || exifRotation != 0) {        synchronized (DECODE_LOCK) {          if (data.needsMatrixTransform() || exifRotation != 0) {            bitmap = transformResult(data, bitmap, exifRotation);            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;  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  1. Dispatcher.performComplete()
//先判断是否要写内存缓存,然后将当前的hunter批量。  //批量的原因是在Picasso的Handler当前可能还有没有处理的。再Dispatcher这一级别再缓冲一下  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");    }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. Picasso.comple()
//从Hunter中取出结果,调用Action.complete,or Action.error  void complete(BitmapHunter hunter) {    Action single = hunter.getAction();    List<Action> joined = hunter.getActions();    boolean hasMultiple = joined != null && !joined.isEmpty();    boolean shouldDeliver = single != null || hasMultiple;    if (!shouldDeliver) {      return;    }    Uri uri = hunter.getData().uri;    Exception exception = hunter.getException();    Bitmap result = hunter.getResult();    LoadedFrom from = hunter.getLoadedFrom();    if (single != null) {      deliverAction(result, from, single);    }    if (hasMultiple) {      //noinspection ForLoopReplaceableByForEach      for (int i = 0, n = joined.size(); i < n; i++) {        Action join = joined.get(i);        deliverAction(result, from, join);      }    }    if (listener != null && exception != null) {      listener.onImageLoadFailed(this, uri, exception);    }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
原创粉丝点击