博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Picasso源码阅读笔记八
阅读量:7011 次
发布时间:2019-06-28

本文共 4107 字,大约阅读时间需要 13 分钟。

Downloader是网络图片下载器。

Downloader.Response

Response是Downloader的下载结果。

class Response {    final InputStream stream; //图片的字节流,和Bitmap只能二选一    final Bitmap bitmap; //图片的位图,和InputStream只能二选一    final boolean cached; //是否是读取磁盘缓存    final long contentLength; //stream的长度}复制代码

自定义Downloader

Downloader是一个接口。自定义Downloader需要实现两个方法。

public interface Downloader {  //根据Uri和网络策略下载图片  @Nullable Response load(@NonNull Uri uri, int networkPolicy) throws IOException;  //关闭下载器,包括关闭磁盘缓存和其他资源  void shutdown();}复制代码

然后把自定义的Downloader通过Picasso.Builder的downloader方法添加到Picasso中。

默认的Downloader

当没有提供自定义Downloader时,Picasso会调用Utils.createDefaultDownloader方法创建默认的Downloader。

static Downloader createDefaultDownloader(Context context) {  if (SDK_INT >= GINGERBREAD) {    //先判断是否使用了okhttp3,如果有则使用OkHttp3Downloader    try {      Class.forName("okhttp3.OkHttpClient");      return OkHttp3DownloaderCreator.create(context);    } catch (ClassNotFoundException ignored) {    }    //判断是否使用了okhttp,如果有则使用OkHttpDownloader    try {      Class.forName("com.squareup.okhttp.OkHttpClient");      return OkHttpDownloaderCreator.create(context);    } catch (ClassNotFoundException ignored) {    }  }  //如果没有okhttp,则使用UrlConnectionDownloader  return new UrlConnectionDownloader(context);}复制代码

OkHttpDownloader和OkHttp3Downloader

OkHttpDownloader和OkHttp3Downloader的区别只是由于okhttp版本不同而导致的客户端创建方式不同而已。下面以OkHttp3Downloader进行说明。 Picasso的Utils为OkHttp3指定了默认的缓存路径和缓存大小。

//缓存路径是应用缓存目录下的picasso-cache文件夹static File createDefaultCacheDir(Context context) {    File cache = new File(context.getApplicationContext().getCacheDir(), PICASSO_CACHE);    if (!cache.exists()) {      cache.mkdirs();    }    return cache;}static long calculateDiskCacheSize(File dir) {    long size = MIN_DISK_CACHE_SIZE;    try {      StatFs statFs = new StatFs(dir.getAbsolutePath());      long blockCount =          SDK_INT < JELLY_BEAN_MR2 ? (long) statFs.getBlockCount() : statFs.getBlockCountLong();      long blockSize =          SDK_INT < JELLY_BEAN_MR2 ? (long) statFs.getBlockSize() : statFs.getBlockSizeLong();      long available = blockCount * blockSize;      //缓存大小是缓存目录磁盘可用空间的2%      size = available / 50;    } catch (IllegalArgumentException ignored) {    }    return Math.max(Math.min(size, MAX_DISK_CACHE_SIZE), MIN_DISK_CACHE_SIZE);}复制代码

使用OkHttp获取网络图片是比较简单的。

@Override public Response load(@NonNull Uri uri, int networkPolicy) throws IOException {	//根据网络策略设置CacheControl    CacheControl cacheControl = null;    if (networkPolicy != 0) {      if (NetworkPolicy.isOfflineOnly(networkPolicy)) {强制读取缓存        cacheControl = CacheControl.FORCE_CACHE;      } else {        CacheControl.Builder builder = new CacheControl.Builder();        if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) { //不先检查缓存是否有目标文件          builder.noCache();        }        if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) { //请求结果不进行缓存          builder.noStore();        }        cacheControl = builder.build();      }    }    Request.Builder builder = new okhttp3.Request.Builder().url(uri.toString());    if (cacheControl != null) {      builder.cacheControl(cacheControl);    }    okhttp3.Response response = client.newCall(builder.build()).execute();    int responseCode = response.code();    if (responseCode >= 300) {      response.body().close();      throw new ResponseException(responseCode + " " + response.message(), networkPolicy,          responseCode);    }    boolean fromCache = response.cacheResponse() != null; //判断是读取磁盘缓存还是读取网络    ResponseBody responseBody = response.body();    return new Response(responseBody.byteStream(), fromCache, responseBody.contentLength());   }  @Override public void shutdown() {    if (!sharedClient) { //如果缓存目录不是共享的,则关闭缓存      if (cache != null) {        try {          cache.close();        } catch (IOException ignored) {        }      }    }}复制代码

UrlConnectionDownloader

UrlConnectionDownloader是通过HttpURLConnection来进行网络请求的。缓存路径、缓存大小、CacheControl设置和OkHttpDownloader是一致的。有区别的一点是,UrlConnectionDownloader发送网络请求是单线程的,所以创建缓存目录时需要加锁避免重复创建。设置CacheControl的字符串使用了ThreadLocal,来保证数据的准确性。

转载于:https://juejin.im/post/5a7ef989f265da4e7a784f87

你可能感兴趣的文章
ORA-00845: MEMORY_TARGET not supported on this system
查看>>
完美解决failed to open stream: HTTP request failed!(file_get_contents引起的)
查看>>
安装包大全
查看>>
Mysql 通过全量备份和binlog恢复整体数据
查看>>
使用paramiko模块在远程服务器执行命令
查看>>
Cannot change version of project facet Dynamic web
查看>>
Nginx中文手册
查看>>
jqgrid saveRow 保存行 编辑数据向后台保存的使用
查看>>
离职后的选择
查看>>
Java编写QQ邮件发送程序
查看>>
JavaWeb
查看>>
我的友情链接
查看>>
Struts2输入<无提示解决方法
查看>>
字符串资源多语言的出错问题
查看>>
集合框架
查看>>
Git 大杂烩(初学git 常用的命令)
查看>>
清除默认样式
查看>>
padding-left: 20%;position: relative; left: 50%;
查看>>
zabbix专题:第七章 添加图像Graphs,添加聚合图形Screens
查看>>
移动端随记:flexbox兼容处理
查看>>