当前位置: 首页 > news >正文

如何选择做网站吴谨含厂家不愿做网站

如何选择做网站,吴谨含厂家不愿做网站,英文网站接单做翻译,网站结构优化自己项目中一直都是用的开源的xUtils框架#xff0c;包括 BitmapUtils、DbUtils、ViewUtils和HttpUtils四大模块#xff0c;这四大模块都是项目中比较常用的。最近决定研究一下 xUtils的源码#xff0c;用了这么久总得知道它的实现原理吧。我是先从先从BitmapUtils模块开始的…   自己项目中一直都是用的开源的xUtils框架包括 BitmapUtils、DbUtils、ViewUtils和HttpUtils四大模块这四大模块都是项目中比较常用的。最近决定研究一下 xUtils的源码用了这么久总得知道它的实现原理吧。我是先从先从BitmapUtils模块开始的。BitmapUtils和大多数图片加载框架一 样都是基于内存-文件-网络三级缓存。也就是加载图片的时候首先从内存缓存中取如果没有再从文件缓存中取如果文件缓存没有取到就从网络下载图片并 且加入内存和文件缓存。   这篇帖子先分析内存缓存是如何实现的。好吧开始进入正题。    BitmapUtils内存缓存的核心类LruMemoryCacheLruMemoryCache代码和v4包的LruCache一样只是加了一 个存储超期的处理这里分析LruCache源码。LRU即Least Recently Used近期最少使用算法。也就是当内存缓存达到设定的最大值时将内存缓存中近期最少使用的对象移除有效的避免了OOM的出现。         讲到LruCache不得不提一下LinkedHashMap因为LruCache中Lru算法的实现就是通过LinkedHashMap来实现 的。LinkedHashMap继承于HashMap它使用了一个双向链表来存储Map中的Entry顺序关系这种顺序有两种一种是LRU顺序一 种是插入顺序这可以由其构造函数public LinkedHashMap(int initialCapacity,float loadFactor, boolean accessOrder)指定。所以对于get、put、remove等操作LinkedHashMap除了要做HashMap做的事情还做些调整 Entry顺序链表的工作。LruCache中将LinkedHashMap的顺序设置为LRU顺序来实现LRU缓存每次调用get(也就是从内存缓存 中取图片)则将该对象移到链表的尾端。调用put插入新的对象也是存储在链表尾端这样当内存缓存达到设定的最大值时将链表头部的对象近期最少用到 的移除。关于LinkedHashMap详解请前往http://www.cnblogs.com/children/archive/2012/10/02/2710624.html。         下面看下LruCache的源码我都注释的很详细了。 1 /2 Copyright (C) 2011 The Android Open Source Project3 4 Licensed under the Apache License, Version 2.0 (the “License”);5 you may not use this file except in compliance with the License.6 You may obtain a copy of the License at7 8 http://www.apache.org/licenses/LICENSE-2.09 10 Unless required by applicable law or agreed to in writing, software11 distributed under the License is distributed on an “AS IS” BASIS,12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 See the License for the specific language governing permissions and14 limitations under the License.15 /1617 package android.support.v4.util;1819 import java.util.LinkedHashMap;20 import java.util.Map;2122 /**23 Static library version of {link android.util.LruCache}. Used to write apps24 that run on API levels prior to 12. When running on API level 12 or above,25 this implementation is still used; it does not try to switch to the26 framework’s implementation. See the framework SDK documentation for a class27 overview.28 /29 public class LruCache {30 private final LinkedHashMap map;3132 /** Size of this cache in units. Not necessarily the number of elements. /33 private int size; //当前cache的大小34 private int maxSize; //cache最大大小3536 private int putCount; //put的次数37 private int createCount; //create的次数38 private int evictionCount; //回收的次数39 private int hitCount; //命中的次数40 private int missCount; //未命中次数4142 /43 param maxSize for caches that do not override {link #sizeOf}, this is44 the maximum number of entries in the cache. For all other caches,45 this is the maximum sum of the sizes of the entries in this cache.46 /47 public LruCache(int maxSize) {48 if (maxSize 0) {49 throw new IllegalArgumentException(“maxSize 0”);50 }51 this.maxSize maxSize;52 //将LinkedHashMap的accessOrder设置为true来实现LRU53 this.map new LinkedHashMap(0, 0.75f, true);54 }5556 /57 Returns the value for {code key} if it exists in the cache or can be58 created by {code #create}. If a value was returned, it is moved to the59 head of the queue. This returns null if a value is not cached and cannot60 be created.61 通过key获取相应的item或者创建返回相应的item。相应的item会移动到队列的尾部62 如果item的value没有被cache或者不能被创建则返回null。63 /64 public final V get(K key) {65 if (key null) {66 throw new NullPointerException(“key null”);67 }6869 V mapValue;70 synchronized (this) {71 mapValue map.get(key);72 if (mapValue ! null) {73 //mapValue不为空表示命中hitCount1并返回mapValue对象74 hitCount;75 return mapValue;76 }77 missCount; //未命中78 }7980 /81 Attempt to create a value. This may take a long time, and the map82 may be different when create() returns. If a conflicting value was83 added to the map while create() was working, we leave that value in84 the map and release the created value.85 如果未命中则试图创建一个对象这里create方法返回null,并没有实现创建对象的方法86 如果需要事项创建对象的方法可以重写create方法。因为图片缓存时内存缓存没有命中会去87 文件缓存中去取或者从网络下载所以并不需要创建。88 /89 V createdValue create(key);90 if (createdValue null) {91 return null;92 }93 //假如创建了新的对象则继续往下执行94 synchronized (this) {95 createCount;96 //将createdValue加入到map中并且将原来键为key的对象保存到mapValue97 mapValue map.put(key, createdValue);98 if (mapValue ! null) {99 // There was a conflict so undo that last put 100 //如果mapValue不为空则撤销上一步的put操作。 101 map.put(key, mapValue); 102 } else { 103 //加入新创建的对象之后需要重新计算size大小 104 size safeSizeOf(key, createdValue); 105 } 106 } 107 108 if (mapValue ! null) { 109 entryRemoved(false, key, createdValue, mapValue); 110 return mapValue; 111 } else { 112 //每次新加入对象都需要调用trimToSize方法看是否需要回收 113 trimToSize(maxSize); 114 return createdValue; 115 } 116 } 117 118 / 119 Caches {code value} for {code key}. The value is moved to the head of 120 the queue. 121 122 return the previous value mapped by {code key}. 123 */ 124 public final V put(K key, V value) { 125 if (key null || value null) { 126 throw new NullPointerException(“key null || value null”); 127 } 128 129 V previous; 130 synchronized (this) { 131 putCount; 132 size safeSizeOf(key, value); //size加上预put对象的大小 133 previous map.put(key, value); 134 if (previous ! null) { 135 //如果之前存在键为key的对象则size应该减去原来对象的大小 136 size - safeSizeOf(key, previous); 137 } 138 } 139 140 if (previous ! null) { 141 entryRemoved(false, key, previous, value); 142 } 143 //每次新加入对象都需要调用trimToSize方法看是否需要回收 144 trimToSize(maxSize); 145 return previous; 146 } 147 148 / 149 param maxSize the maximum size of the cache before returning. May be -1 150 to evict even 0-sized elements. 151 此方法根据maxSize来调整内存cache的大小如果maxSize传入-1则清空缓存中的所有对象 152 / 153 private void trimToSize(int maxSize) { 154 while (true) { 155 K key; 156 V value; 157 synchronized (this) { 158 if (size 0 || (map.isEmpty() size ! 0)) { 159 throw new IllegalStateException(getClass().getName() 160 “.sizeOf() is reporting inconsistent results!”); 161 } 162 //如果当前size小于maxSize或者map没有任何对象,则结束循环 163 if (size maxSize || map.isEmpty()) { 164 break; 165 } 166 //移除链表头部的元素并进入下一次循环 167 Map.Entry toEvict map.entrySet().iterator().next(); 168 key toEvict.getKey(); 169 value toEvict.getValue(); 170 map.remove(key); 171 size - safeSizeOf(key, value); 172 evictionCount; //回收次数1 173 } 174 175 entryRemoved(true, key, value, null); 176 } 177 } 178 179 / 180 Removes the entry for {code key} if it exists. 181 182 return the previous value mapped by {code key}. 183 从内存缓存中根据key值移除某个对象并返回该对象 184 */ 185 public final V remove(K key) { 186 if (key null) { 187 throw new NullPointerException(“key null”); 188 } 189 190 V previous; 191 synchronized (this) { 192 previous map.remove(key); 193 if (previous ! null) { 194 size - safeSizeOf(key, previous); 195 } 196 } 197 198 if (previous ! null) { 199 entryRemoved(false, key, previous, null); 200 } 201 202 return previous; 203 } 204 205 / 206 Called for entries that have been evicted or removed. This method is 207 invoked when a value is evicted to make space, removed by a call to 208 {link #remove}, or replaced by a call to {link #put}. The default 209 implementation does nothing. 210 211 The method is called without synchronization: other threads may 212 access the cache while this method is executing. 213 214 param evicted true if the entry is being removed to make space, false 215 if the removal was caused by a {link #put} or {link #remove}. 216 param newValue the new value for {code key}, if it exists. If non-null, 217 this removal was caused by a {link #put}. Otherwise it was caused by 218 an eviction or a {link #remove}. 219 / 220 protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {} 221 222 / 223 Called after a cache miss to compute a value for the corresponding key. 224 Returns the computed value or null if no value can be computed. The 225 default implementation returns null. 226 227 The method is called without synchronization: other threads may 228 access the cache while this method is executing. 229 230 If a value for { code key} exists in the cache when this method 231 returns, the created value will be released with {link #entryRemoved} 232 and discarded. This can occur when multiple threads request the same key 233 at the same time (causing multiple values to be created), or when one 234 thread calls {link #put} while another is creating a value for the same 235 key. 236 / 237 protected V create(K key) { 238 return null; 239 } 240 241 private int safeSizeOf(K key, V value) { 242 int result sizeOf(key, value); 243 if (result 0) { 244 throw new IllegalStateException(“Negative size: “ key “” value); 245 } 246 return result; 247 } 248 249 / 250 Returns the size of the entry for {code key} and {code value} in 251 user-defined units. The default implementation returns 1 so that size 252 is the number of entries and max size is the maximum number of entries. 253 254 An entry’s size must not change while it is in the cache. 255 用来计算单个对象的大小这里默认返回1一般需要重写该方法来计算对象的大小 256 xUtils中创建LruMemoryCache时就重写了sizeOf方法来计算bitmap的大小 257 mMemoryCache new LruMemoryCache(globalConfig.getMemoryCacheSize()) { 258 Override 259 protected int sizeOf(MemoryCacheKey key, Bitmap bitmap) { 260 if (bitmap null) return 0; 261 return bitmap.getRowBytes() bitmap.getHeight(); 262 } 263 }; 264 265 / 266 protected int sizeOf(K key, V value) { 267 return 1; 268 } 269 270 /** 271 Clear the cache, calling {link #entryRemoved} on each removed entry. 272 清空内存缓存 273 / 274 public final void evictAll() { 275 trimToSize(-1); // -1 will evict 0-sized elements 276 } 277 278 / 279 For caches that do not override {link #sizeOf}, this returns the number 280 of entries in the cache. For all other caches, this returns the sum of 281 the sizes of the entries in this cache. 282 / 283 public synchronized final int size() { 284 return size; 285 } 286 287 / 288 For caches that do not override {link #sizeOf}, this returns the maximum 289 number of entries in the cache. For all other caches, this returns the 290 maximum sum of the sizes of the entries in this cache. 291 / 292 public synchronized final int maxSize() { 293 return maxSize; 294 } 295 296 / 297 Returns the number of times {link #get} returned a value. 298 / 299 public synchronized final int hitCount() { 300 return hitCount; 301 } 302 303 / 304 Returns the number of times {link #get} returned null or required a new 305 value to be created. 306 / 307 public synchronized final int missCount() { 308 return missCount; 309 } 310 311 /** 312 Returns the number of times {link #create(Object)} returned a value. 313 / 314 public synchronized final int createCount() { 315 return createCount; 316 } 317 318 /** 319 Returns the number of times {link #put} was called. 320 / 321 public synchronized final int putCount() { 322 return putCount; 323 } 324 325 /** 326 Returns the number of values that have been evicted. 327 / 328 public synchronized final int evictionCount() { 329 return evictionCount; 330 } 331 332 /** 333 Returns a copy of the current contents of the cache, ordered from least 334 recently accessed to most recently accessed. 335 / 336 public synchronized final Map snapshot() { 337 return new LinkedHashMap(map); 338 } 339 340 Override public synchronized final String toString() { 341 int accesses hitCount missCount; 342 int hitPercent accesses ! 0 ? (100 * hitCount / accesses) : 0; 343 return String.format(“LruCache[maxSize%d,hits%d,misses%d,hitRate%d%%]”, 344 maxSize, hitCount, missCount, hitPercent); 345 } 346 } 看完代码是不是觉得内存缓存的实现其实很简单
http://www.zqtcl.cn/news/890384/

相关文章:

  • 企业网站维护wordpress特效代码
  • 建设银行网站短信错误6次wordpress新主题去版权
  • 国外 配色网站天猫店购买交易平台
  • 网站推广广告词大全集网站和网络建设自查报告
  • 电子商务网站建设备案须知自己做的网站服务器在哪里
  • 怎样用wordpress做网站wordpress 首页判断
  • jsp做的网站效果织梦网站程序模板
  • 展示型网站设计公司网盘wordpress
  • 网站建设 保密学服装设计后悔了
  • 网站建设前端和后端网站开发所遵循的
  • 有自己域名的个人网站企业网站建设制作公司
  • 工程行业网站优化网站推广排名
  • 青岛网站建设软件下载广州app网站建设
  • 天津市建设厅官方网站qq电脑版登录
  • 贵阳手机网站建设公司辽源网站建设
  • 淄博网站设计制作wordpress 纯静态首页
  • 规划电子商务网站流程福清建设局网站简介
  • 使用joomla的网站网络营销师资格证有什么用
  • 做经营网站怎么赚钱吗关于做网站的合同
  • 上海手机网站建设哪家好重庆景点
  • 做网站菜单背景图片wordpress伪原创词库
  • 网络维护工程师工资多少聊城哪里做优化网站
  • 网站开发用什么字体查询域名备案
  • 济南品牌网站建设公司网站单个页面紧张搜索引擎蜘蛛
  • 公司需要一个简单的网站包头网站建设奥北
  • 怎么制作网站导航页新手做网站详细步骤
  • 自己个人网站后台怎么做wordpress多程序用户同步
  • 赣州网联科技有限公司wordpress安装后优化
  • 二手书的网站建设做设计在哪个网站找图片大全
  • 网站seo设计北京市建设投标网站