北京做网站商标的公司,百度app常用网址在哪里,局 网站建设方案,wordpress文章中标签引言使用微信时我们会发现#xff0c;首次进入微信的好友列表时#xff0c;会加载好友头像#xff0c;但是再次进入时#xff0c;就不用重新加载了#xff0c;而且其他页面都不用重新加载#xff0c;说明微信的好友头像是缓存在本地的#xff0c;然后好友修改头像后首次进入微信的好友列表时会加载好友头像但是再次进入时就不用重新加载了而且其他页面都不用重新加载说明微信的好友头像是缓存在本地的然后好友修改头像后又会及时的更新这个功能是如何实现的呢我们来分析一下分析关于头像缓存的实现头像是网络图片而且数据量较大如果用我们常用的SharedPreferences将头像以Bitmap的形式存储势必会造成OOM这个方法是行不通的我们存储的只能是图片的地址但是如果只存储地址的话要转化成图片还是要通过网络请求重新加载达不到我们要求的效果所以我们需要在磁盘中单独开辟一块空间将头像以Bitmap的形式进行存储如何实现呢其实关于网络图片的缓存有很多开源的第三方框架比较可靠好用的如xUtils,Glide,volley,Universal-Image-Loader,Picasso,Fresco等等。下面我们以常用的xUtils为例首先对BitmapUtils的实例化对于磁盘缓存路径磁盘缓存空间大小内存缓存的空间大小内存缓存百分比可以自定义也可以使用默认配置代码如下/*** param context 上下文*/public BitmapUtils(Context context) {this(context,null);}/*** param context 上下文* param diskCachePath 磁盘高速缓存路径*/public BitmapUtils(Context context,String diskCachePath) {if (context null) {throw new IllegalArgumentException(context may not be null);}this.context context.getApplicationContext();globalConfig BitmapGlobalConfig.getInstance(this.context,diskCachePath);defaultDisplayConfig new BitmapDisplayConfig();}/**** param context 上下文* param diskCachePath 磁盘高速缓存路径* param memoryCacheSize 内存缓存空间大小*/public BitmapUtils(Context context,String diskCachePath,int memoryCacheSize) {this(context,diskCachePath);globalConfig.setMemoryCacheSize(memoryCacheSize);}/**** param context 上下文* param diskCachePath 磁盘高速缓存路径* param memoryCacheSize 内存缓存空间大小* param diskCacheSize 磁盘高速缓存空间大小*/public BitmapUtils(Context context,int memoryCacheSize,int diskCacheSize) {this(context,diskCachePath);globalConfig.setMemoryCacheSize(memoryCacheSize);globalConfig.setDiskCacheSize(diskCacheSize);}/**** param context 上下文* param diskCachePath 磁盘高速缓存路径* param memoryCachePercent 内存缓存百分比*/public BitmapUtils(Context context,float memoryCachePercent) {this(context,diskCachePath);globalConfig.setMemCacheSizePercent(memoryCachePercent);}/**** param context 上下文* param diskCachePath 磁盘高速缓存路径* param memoryCachePercent 内存缓存百分比* param diskCacheSize 磁盘缓存空间大小*/public BitmapUtils(Context context,float memoryCachePercent,diskCachePath);globalConfig.setMemCacheSizePercent(memoryCachePercent);globalConfig.setDiskCacheSize(diskCacheSize);}一般情况下我们只需要使用默认配置就可以了即BitmapUtils bitmap new BitmapUtils(context);然后对图片的缓存和显示/*** 根据图片路径显示到具体的View上* param container 要把图片显示到的View* param uri 图片路径*/public void display(T container,String uri) {display(container,uri,null,null);}/*** 根据图片路径显示到具体的View上* param container 要把图片显示到的View* param uri 图片路径* param displayConfig*/public void display(T container,String uri,BitmapDisplayConfig displayConfig) {display(container,displayConfig,null);}/*** 根据图片路径显示到具体的View上* param container 要把图片显示到的View* param uri 图片路径* param callBack 加载过程回调各种状态*/public void display(T container,BitmapLoadCallBack callBack) {display(container,callBack);}/*** 根据图片路径显示到具体的View上* param container 要把图片显示到的View* param uri 图片路径* param displayConfig 位图显示配置* param callBack*/public void display(T container,BitmapDisplayConfig displayConfig,BitmapLoadCallBack callBack) {if (container null) {return;}if (callBack null) {callBack new DefaultBitmapLoadCallBack();}if (displayConfig null || displayConfig defaultDisplayConfig) {displayConfig defaultDisplayConfig.cloneNew();}// Optimize MaxBitmapSize size displayConfig.getBitmapMaxSize();SizedisplayConfig.setBitmapMaxSize(BitmapCommonUtils.optimizeMaxSizeByView(container,size.getWidth(),size.getHeight()));container.clearAnimation();if (TextUtils.isEmpty(uri)) {callBack.onLoadFailed(container,displayConfig.getLoadFailedDrawable());return;}// start loadingcallBack.onPreLoad(container,displayConfig);// find bitmap from mem cache.Bitmap bitmap globalConfig.getBitmapCache().getBitmapFromMemCache(uri,displayConfig);if (bitmap ! null) {callBack.onLoadStarted(container,displayConfig);callBack.onLoadCompleted(container,bitmap,BitmapLoadFrom.MEMORY_CACHE);} else if (!bitmapLoadTaskExist(container,callBack)) {final BitmapLoadTask loadTask new BitmapLoadTask(container,callBack);// get executorPriorityExecutor executor globalConfig.getBitmapLoadExecutor();File diskCacheFile this.getBitmapFileFromDiskCache(uri);boolean diskCacheExist diskCacheFile ! null diskCacheFile.exists();if (diskCacheExist executor.isBusy()) {executor globalConfig.getDiskCacheExecutor();}// set loading imageDrawable loadingDrawable displayConfig.getLoadingDrawable();callBack.setDrawable(container,new AsyncDrawable(loadingDrawable,loadTask));loadTask.setPriority(displayConfig.getPriority());loadTask.executeOnExecutor(executor);}}从这段代码中我们可以看到当要加载某张图片时会根据图片地址进行查找是否有对应的bitmap缓存图片如果有就直接引用缓存如果没有就加载并缓存所以我们对图片的缓存只需要实现以上方法就可以了而且只要设置相同的缓存路径就可以实现一个页面缓存后其他页面有相同图片也可以调用。那么缓存之后好友更新头像又是怎么做到即时更新的呢缓存后如何实现即时更新头像根据查阅的资料可以归结为以下几种实现方式1.在服务器返回用户数组时多加一个字段头像最后一次修改时间或者修改过几次等标志符与缓存进行比较是否有变化2.利用图片的checkSum来实现如果check到这个数字有变化就会自动去更新3.利用socket监听,当好友头像更新时候首先会告诉服务器,服务器将变化通知推送到所有好友,好友监听收到通知后自动更新第一种方法和第二种方法本质是一致的通过请求服务器的数据与本地缓存进行对比是由客户端处理的第三种方法的话你换一次头像就要服务器去提醒你的所有好友一遍服务器压力会不会比较大仔细去研究一下微信就会发现当好友头像修改后如果你停留在某个页面进入的这个页面是之前进入过的还没有销毁头像是不会改变的你需要打开一个新的页面或者重新进入微信才会更新头像由此看出微信并不是用的第三种方式而是采用了前两种方式的实现原理只有在创建一个Activity或fragment时调用接口读取服务器数据时才会更新头像总结通过以上的分析我们基本捋清了思路要实现类似微信的缓存和更新还有头像先是在磁盘开辟一个空间用于读写头像的Bitmap然后创建页面时读取服务器数据和本地缓存进行比较如果有变化就进行更新以上就是本文的全部内容希望对大家的学习有所帮助也希望大家多多支持编程小技巧。总结如果觉得编程之家网站内容还不错欢迎将编程之家网站推荐给程序员好友。本图文内容来源于网友网络收集整理提供作为学习参考使用版权属于原作者。小编个人微信号 jb51ccc喜欢与人分享编程技术与工作经验欢迎加入编程之家官方交流群