Picasso源码分析4

xiaoxiao2021-02-28  131

0使用手册

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

1使用方法简介

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

2 基本原理

先使用Picasso.Builder生成一个单例Picasso,load的时候生成一个RequestCreator,再设置不同的Reqeust参数,into的时候生成一个Request,再将Request和Target组合成Action,由Picasso交给Dispatcher后台执行,Dispatcher用Action生成BitmapHunter,交于PicassoExecutorService执行,BitmapHunter下载完成,执行相应的变换后,用Handler通知Dispatcher缓存在内存中,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源代码分析

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); } 12345678910111213141516171819202122232425262728 12345678910111213141516171819202122232425262728 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); } 123456789101112131415161718192021222324252627282930313233343536373839404142 123456789101112131415161718192021222324252627282930313233343536373839404142 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; } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 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"); } } 123456789101112 123456789101112 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); } } 123456789101112131415161718192021222324252627282930313233 123456789101112131415161718192021222324252627282930313233
转载请注明原文地址: https://www.6miu.com/read-34744.html

最新回复(0)