Thinking in Google Doc-图片框架的实现及布局优化

简介:

学习谷歌文档,总结如下:


1.图片加载框架的封装

    1)利用HttpURLConnection来封装网络加载图片的方法

    2)创建自定义的AsyncTask来封装1)中加载网络图片的方法,并显示到控件上。

    3)暴露方法封装2)中自定义的加载并显示图片的AsyncTask

    走完上面这几步,只需调用一个方法,就可以从网络上加载一张图片并且显示到控件上了。

  

  解决List并发下载图片错位的问题     

  但是,谷歌文档中说上面代码会存在一个问题。就是如果在List里使用,复用的话,可能会发生图

  图片错位的问题:就是某个item显示的图片,可能显示的图片是之前的item的图片。因为之前的这

  张图片可能加载时间比较长,滑动后imageview是复用的,所以后面的item可能会显示之前的item的

  图片。


  这种就是由于并发产生的问题,谷歌工程师是这么解决问题的:

  1》定义一个类 class DownloadedDrawable extends ColorDrawable,然后将下载的异步任务

    DownloadAsyncTask与其绑定起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void      display(Context context,String url, ImageView imageView) {
         Bitmap bitmapFromMemCache = LruCacheUtil.getBitmapFromMemCache(url);
         if (bitmapFromMemCache !=  null ){
             imageView.setImageBitmap(bitmapFromMemCache);
         } else {
             if  (cancelPotentialDownload(url, imageView)) {
                 BitmapDownloaderTask task =  new  BitmapDownloaderTask(context,imageView);
                 DownloadedDrawable downloadedDrawable =  new  DownloadedDrawable(task);
                 imageView.setImageDrawable(downloadedDrawable);
                 task.execute(url);
             }
         }
     }

  2》定义2个方法 

    BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) 

     --得到与ImageView绑定的异步下载任务   

1
2
3
4
5
6
7
8
9
10
     public  static      BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
         if  (imageView !=  null ) {
             Drawable drawable = imageView.getDrawable();
             if  (drawable  instanceof  DownloadedDrawable) {
                 DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
                 return  downloadedDrawable.getBitmapDownloaderTask();
             }
         }
         return  null ;
     }

 

    boolean cancelPotentialDownload(String url, ImageView imageView) 

    --取消可能正在进行的下载,并返回是否已经取消。   

      如果与imageView绑定的下载任务不为空,再判断与ImageView绑定的异步下载任务的URL,如果

   为null或者是与当前方法传递进来URL不一致,说明异步下载任务正在执行之前的下载,就取消任

   务,否则说明任务正在执行中且url一致,就不重新开启任务。  

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
     private  static  boolean      cancelPotentialDownload(String url, ImageView imageView) {
         BitmapDownloaderTask bitmapDownloaderTask = BitmapDownloaderTask.getBitmapDownloaderTask(imageView);
     
         if  (bitmapDownloaderTask !=  null ) {
             String bitmapUrl = bitmapDownloaderTask.url;
             if  ((bitmapUrl ==  null ) || (!bitmapUrl.equals(url))) {
                 bitmapDownloaderTask.cancel( true );
             else  {
                 // The same URL is already being downloaded.
                 return  false ;
             }
         }
         return  true ;
     }

   解决图片缓存的问题  

    1》用内存来缓存,使用LruCache这个类。

     内存的特点:

       内存加载速度比较快,但是内存在开关机之后会被回收,缓存的数据会消失。

     底层:

      LinkedHashMap来实现存储    

     实现原理:

       当从url下载图片之前,先判断缓存中存不存在图片,如果存在直接加载图片,不存在则

      去网络请求图片。

       当AsyncTask下载完图片之后,如果不为null,就存放到缓存中。

      于是我写了个工具类LruCacheUtils来完成图片的缓存

      

      

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
     public  class      LruCacheUtil {
         //LruCache for bitmap
         private  static  LruCache<String, Bitmap> mMemoryCache;
         static  {
             // Get max available VM memory, exceeding this amount will throw an
             // OutOfMemory exception. Stored in kilobytes as LruCache takes an
             // int in its constructor.
             final  int  maxMemory = ( int ) (Runtime.getRuntime().maxMemory() /  1024 );
     
             // Use 1/8th of the available memory for this memory cache.
             final  int  cacheSize = maxMemory /  8 ;
     
             mMemoryCache =  new  LruCache<String, Bitmap>(cacheSize) {
                 @TargetApi (Build.VERSION_CODES.HONEYCOMB_MR1)
                 @Override
                 protected  int  sizeOf(String key, Bitmap bitmap) {
                     // The cache size will be measured in kilobytes rather than
                     // number of items.
                     return  bitmap.getByteCount() /  1024 ;
                 }
             };
         }
     
         public  static  void  addBitmapToMemoryCache(String key, Bitmap bitmap) {
             if  (getBitmapFromMemCache(key) ==  null ) {
                 mMemoryCache.put(key, bitmap);
             }
         }
     
         public  static  Bitmap getBitmapFromMemCache(String key) {
             return  mMemoryCache.get(key);
         }
     }

   2》使用磁盘(Disk)来缓存,使用DiskLruCache(这个类google文档里并没有提供)

     Android DiskLruCache 源码解析 硬盘缓存的绝佳方案

    http://blog.csdn.net/lmj623565791/article/details/47251585

    下载链接

     http://http://www.oschina.net/p/disklrucache

    Android本地缓存DiskLruCache完整详细学习示例

    http://www.2cto.com/kf/201501/368172.html 

     

    虽然利用内存来缓存,加载图片的时候速度比较快,但是像GridView会很快地占满内存。当应

     用非正常关闭(如被电话应用打断、运行在后台的时候被杀死)会导致cache被销毁清空。

     注意:获取图片应该在后台进行 

      Of course, fetching images from disk is slower than loading from memory and should be done in a       

                      background thread, as disk read times can be unpredictable.(from google doc)

      

     缓存位置:

       有外部存储设备就存放到外部存储设备中,否则存放到应用包名目录下。


2.布局优化

   sdk下的一些工具并不是专门针对Eclipse的,Android Studio也可以使用。  

   sdk/tools下的工具Hierarchy Viewer

   http://wear.techbrood.com/training/improving-layouts/optimizing-layout.html#Inspect

   爽处1:可以查看布局结构某个节点的3个方法Measure、Layout、Draw执行所需要的时间,这样

        如果某个item的加载时间比较长,你就应该要优化了。

        

   使用这个工具可能会遇到的问题:

   问题:使用Hierarchyviewer,measure、layout、draw时间未显示?

   解决办法:点击菜单 Profile Node,重新加载之后就有了 

用Hierarchyviewer,measure、layout、draw时间未显示? 

         




      本文转自屠夫章哥  51CTO博客,原文链接:http://blog.51cto.com/4259297/1710561,如需转载请自行联系原作者



相关文章
|
6月前
|
缓存 Java Maven
深入解析Google Guava库与Spring Retry重试框架
深入解析Google Guava库与Spring Retry重试框架
|
数据可视化 JavaScript 前端开发
Google开源了可视化编程框架Visual Blocks for ML
Visual Blocks for ML是一个由Google开发的开源可视化编程框架。它使你能够在易于使用的无代码图形编辑器中创建ML管道。
239 0
|
7月前
|
JSON Android开发 数据格式
Android框架-Google官方Gson解析,android开发实验报告总结
Android框架-Google官方Gson解析,android开发实验报告总结
|
数据采集 搜索推荐 安全
如何做好英文Google优化?
答案是:做足够多的GPB外链+足够多的优质内容。 理解目标受众 为了成功地进行英文Google优化,首先要深入了解您的目标受众。 这包括他们的搜索习惯、使用的关键词,以及他们在搜索结果中期待看到的内容。 选择合适的关键词 在Google优化中,关键词研究至关重要。 确保选择的关键词与您的内容高度相关,并具有适当的搜索量。 利用专业的关键词工具来为您的英文内容找到最佳关键词。
102 0
如何做好英文Google优化?
|
7月前
|
设计模式 前端开发 JavaScript
AngularJS是一款由Google收购的JavaScript结构框架
【5月更文挑战第2天】AngularJS是Google收购的JavaScript框架,用于构建动态Web应用,基于MVC模式,强调模块化和双向数据绑定。它简化了视图与模型的同步,通过语义化标签和依赖注入提升开发效率。适用于复杂单页面应用(SPA),但不适合DOM操作密集型或性能要求极高的场景。
73 0
|
7月前
google测试框架
google测试框架
44 0
|
关系型数据库 MySQL API
Go语言微服务框架 - 6.用Google风格的API接口打通MySQL操作
随着RPC与MySQL的打通,整个框架已经开始打通了数据的出入口。 接下来,我们就尝试着实现通过RPC请求操作MySQL数据库,打通整个链路,真正地让这个平台实现可用。
51 0
|
JSON Cloud Native 网络协议
gRPC简介: Google的高性能RPC框架
gRPC简介: Google的高性能RPC框架
268 0
|
数据采集 安全 搜索推荐
如何选择优质的Google优化关键词?
答案是:选择竞争难度低且有一定流量的关键词。 在当下数字化市场竞争尤为激烈的背景下,选择合适的Google优化关键词无疑是提高网站排名和吸引流量的重中之重。 正确的关键词可以将你的目标用户精准地引导至你的网站,从而实现更高的转化率。 为此,以下提供了选择Google优化关键词的步骤和技巧。 了解你的目标受众 确定受众兴趣 首先,你需要明确你的目标受众,并了解他们在进行搜索时会使用哪些词汇。 这样,你可以找到与他们需求和兴趣相对应的关键词。
96 0
如何选择优质的Google优化关键词?
|
数据采集 搜索推荐 安全
英文网站该如何做站内Google优化?
答案是:英文SEO可以持续建设GPB外链+优质内容可提升排名。 优化内容质量 编写原创和高质量的内容 Google优化中,内容是王道。 确保您的网站内容是原创的,有价值的,并且是针对目标受众的。 优秀的内容不仅可以提升用户体验,也会被搜索引擎更好的认可。 使用适当的标题和子标题 标题和子标题不仅可以使内容更易读,还有助于Google更好的理解您的内容。 确保每个页面都有一个独特且相关的标题,子标题也要能准确反映内容的主题。
83 0
英文网站该如何做站内Google优化?