`
liujianguangaaa
  • 浏览: 236973 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

android UI 优化系列之 创建RGB565的缓存

阅读更多

关于如何优化activity的启动速度, view 的绘制速度, 可参考这个sdk里的文档。 android-sdk-windows-1.5_r1/docs/resources/articles/window-bg-speed.html。
看完后你就知道 android:windowBackground 太重要了,影响到绘制效率。
这里要说的是另外一点, 不是这个windowBackground 。
android 为了提高滚动等各方面的绘制速度,可以为每一个view建立一个缓存,使用 View.buildDrawingCache为自己的view 建立相应的缓存,
这 个所谓的缓存,实际上就是一个Bitmap对象。只是 这个 bitmap 对象可以有多种格式而已,如
Bitmap.Config.ARGB_8888;
Bitmap.Config.ARGB_4444;
Bitmap.Config.ARGB_8888;
Bitmap.Config.ARGB_8888;
Bitmap.Config.RGB_565;
默认的格式是Bitmap.Config.ARGB_8888.,但大多数嵌入式设备使用的显示格式都是Bitmap.Config.RGB_565. 对于后者, 并没有
alpha 值,所以绘制的时候不需要计算alpha合成,速递当让快些。其次,RGB_565可以直接使用优化了的memcopy函数,效率相对高出许多。


所以, 在用buildDrawingCache建立缓存时, 可以使用RGB_565格式。但是如何制定这个格式呢 ?buildDrawingCache有两个版本, buildDrawingCache(boolean) 和 buildDrawingCache()。并没有任何参数可以设置rgb格式,看看源码先:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
public void buildDrawingCache(boolean autoScale) {
        if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ?
                (mDrawingCache == null || mDrawingCache.get() == null) :
                (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {
            if (ViewDebug.TRACE_HIERARCHY) {
                ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
            }
            if (Config.DEBUG && ViewDebug.profileDrawing) {
                EventLog.writeEvent(60002, hashCode());
            }
            int width = mRight - mLeft;
            int height = mBottom - mTop;
            final AttachInfo attachInfo = mAttachInfo;
            final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
            if (autoScale && scalingRequired) {
                width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
                height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
            }
            final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
            final boolean opaque = drawingCacheBackgroundColor != 0 ||
                (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE);
            if (width <= 0 || height <= 0 ||
                    (width * height * (opaque ? 2 : 4) > // Projected bitmap size in bytes
                            ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
                destroyDrawingCache();
                return;
            }
            boolean clear = true;
            Bitmap bitmap = autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
                    (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
            if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
                Bitmap.Config quality;
                if (!opaque) {
                    switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
                        case DRAWING_CACHE_QUALITY_AUTO:
                            quality = Bitmap.Config.ARGB_8888;
                            break;
                        case DRAWING_CACHE_QUALITY_LOW:
                            quality = Bitmap.Config.ARGB_4444;
                            break;
                        case DRAWING_CACHE_QUALITY_HIGH:
                            quality = Bitmap.Config.ARGB_8888;
                            break;
                        default:
                            quality = Bitmap.Config.ARGB_8888;
                            break;
                    }
                } else {
                    quality = Bitmap.Config.RGB_565;
                }
                // Try to cleanup memory
                if (bitmap != null) bitmap.recycle();
                try {
                    bitmap = Bitmap.createBitmap(width, height, quality);
                    bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
                    if (autoScale) {
                        mDrawingCache = new SoftReference<Bitmap>(bitmap);
                    } else {
                        mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);
                    }
                } catch (OutOfMemoryError e) {
                    // If there is not enough memory to create the bitmap cache, just
                    // ignore the issue as bitmap caches are not required to draw the
                    // view hierarchy
                    if (autoScale) {
                        mDrawingCache = null;
                    } else {
                        mUnscaledDrawingCache = null;
                    }
                    return;
                }
                clear = drawingCacheBackgroundColor != 0;
            }
            Canvas canvas;
            if (attachInfo != null) {
                canvas = attachInfo.mCanvas;
                if (canvas == null) {
                    canvas = new Canvas();
                }
                canvas.setBitmap(bitmap);
                // Temporarily clobber the cached Canvas in case one of our children
                // is also using a drawing cache. Without this, the children would
                // steal the canvas by attaching their own bitmap to it and bad, bad
                // thing would happen (invisible views, corrupted drawings, etc.)
                attachInfo.mCanvas = null;
            } else {
                // This case should hopefully never or seldom happen
                canvas = new Canvas(bitmap);
            }
            if (clear) {
                bitmap.eraseColor(drawingCacheBackgroundColor);
            }
            computeScroll();
            final int restoreCount = canvas.save();
            if (autoScale && scalingRequired) {
                final float scale = attachInfo.mApplicationScale;
                canvas.scale(scale, scale);
            }
            canvas.translate(-mScrollX, -mScrollY);
            mPrivateFlags |= DRAWN;
            // Fast path for layouts with no backgrounds
            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                if (ViewDebug.TRACE_HIERARCHY) {
                    ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
                }
                mPrivateFlags &= ~DIRTY_MASK;
                dispatchDraw(canvas);
            } else {
                draw(canvas);
            }
            canvas.restoreToCount(restoreCount);
            if (attachInfo != null) {
                // Restore the cached Canvas for our siblings
                attachInfo.mCanvas = canvas;
            }
            mPrivateFlags |= DRAWING_CACHE_VALID;
        }
    }

看完后明白了,至少跟两个因素有关 drawingCacheBackgroundColor 和 mBGDrawable.
用 setDrawingCacheBackgroundColor(0xffff0000)设置为 非默认颜色后,建立的缓存就是rgb565了,可以用下列方法验证一下:

1
2
3
4
5
6
final Bitmap cache = mContent.getDrawingCache();
            if (cache != null) {
             Config cfg = cache.getConfig();
             Log.d(TAG, "----------------------- cache.getConfig() = " + cfg);
 
        }

分享到:
评论

相关推荐

    Android获取图片的RGB值

    在Android平台上,获取图片的RGB值是图像处理和分析中常见的需求。RGB(Red, Green, Blue)是一种颜色模型,用于表示屏幕上显示的颜色,每个颜色通道(红、绿、蓝)都有0到255的取值范围,组合起来可以产生数百万种...

    android 图片加载优化

    针对这一问题,我们需要深入理解Android系统的内存机制,并学习一系列的图片加载优化策略。 首先,了解Android的内存模型是必要的。Android系统为每个应用分配一定的内存,当应用的内存使用超出限制时,就会触发OOM...

    Android性能优化.pdf

    对于Bitmap,应计算合适的inSampleSize以减小图片尺寸,选择适当的解码格式,如RGB_565,以降低内存消耗。此外,对于大图片,可以考虑分段加载。复用对象也是节省内存的有效手段,比如使用对象池对某些类型的对象...

    Android源码——Google官网的图片缓存源码.7z

    在缓存过程中,需要考虑图片的解码格式(如ARGB_8888、RGB_565等),以平衡图片质量与内存占用。 5. **异步加载**:为了保证UI流畅,图片加载通常在后台线程进行。Glide使用了FutureTarget和RequestManager等组件,...

    android_拖动图片_获取图片上的RGB值并显示到别的控件

    在Android平台上,开发一款应用程序,实现用户可以拖动图片并实时获取图片上任意位置的RGB值,是一项结合图像处理和用户交互的技术。这个功能对于图像编辑、颜色分析或者色彩匹配等应用场景非常有用。以下是实现这一...

    android 图片缓存

    同时,使用ARGB_8888以外的像素格式(如RGB_565)也可以降低内存消耗。 5. **异步加载**:为了防止因图片加载导致UI卡顿,图片加载通常在后台线程进行,加载完成后通过Handler或Callback更新UI。现在大多数图片库如...

    Bitmap高效加载及图片缓存demo

    Bitmap高效加载及图片缓存是Android开发中的重要技术,它涉及到内存管理、性能优化和用户体验。Bitmap对象在Android系统中用于表示图像数据,但如果不合理使用,可能导致内存溢出、应用卡顿等问题。本示例代码旨在...

    Android实现从缓存中读取图片与异步加载功能类.zip

    1. 使用Bitmap.Config配置:根据需求选择ARGB_8888、RGB_565等不同的颜色模式,以降低内存消耗。 2. 使用Target对象:在异步加载库中,通过Target对象可以控制图片加载完成后的显示位置。 3. 使用Glide的...

    Android异步加载图像小结 (含线程池,缓存方法).zip

    为了保证用户体验,我们需要有效地异步加载图像,避免UI线程阻塞,同时考虑到性能优化,使用线程池和缓存策略是必不可少的。本篇文章将深入探讨如何在Android中实现这些技术。 1. **异步加载** - **AsyncTask**:...

    安卓Android源码——安卓Android创建抗锯齿透明背景圆角图像.zip

    本主题聚焦于如何在Android系统中创建抗锯齿、透明背景以及圆角的图像,这对于UI设计和用户体验至关重要。Android源码分析将帮助我们深入理解这个过程。 首先,我们需要了解Android中的图像处理基础。在Android中,...

    Android UI开发(五)Bitmap和Canvas实例.docx

    在Android UI开发中,Bitmap和Canvas是两个非常重要的概念,它们是实现自定义视图、图形绘制和图像处理的关键工具。Bitmap是Android中用于表示位图图像的数据结构,而Canvas则是一个画布,用于在屏幕上绘制这些位图...

    Android异步加载图像小结 (含线程池,缓存方法)毕业设计—(包含完整源码可运行).zip

    本项目是关于Android异步加载图像的一个毕业设计,涵盖了线程池和缓存机制的实现,目的是优化图片加载性能,避免UI阻塞,并节省网络资源。这里我们将详细讨论其中涉及的知识点。 1. **异步加载**: - 在Android中...

    Android性能优化(七)Bitmap内存压缩示例源码BitMapCache.zip

    我们可以根据需求选择更低位深度的格式,如RGB_565,它每像素只占用2字节,但牺牲了透明度。 3. **使用BitmapFactory.decodeResource()的优化**:在从资源文件加载Bitmap时,应使用`BitmapFactory.decodeResource()...

    Google 官方 Android DisplayBimaps的优化事例

    在Android开发中,图片处理是性能优化的重要环节,特别是在处理大量图像或高分辨率图片时,内存管理和渲染效率显得尤为重要。Google官方对Android显示Bitmaps进行了深入优化,旨在提高用户体验,减少应用崩溃,以及...

    android中的位图操作demo

    `Bitmap.Config`定义了位图的颜色模式,如ARGB_8888(32位,透明),RGB_565(16位,不透明),Alpha_8(8位,只有透明度)。选择合适的配置可以节省内存。 3. **位图的绘制**:在Android中,我们通常使用`Canvas`...

    Android演化理解 Android 异步加载图片.zip源码资源下载

    JPEG和PNG压缩算法可以减小图片大小,Bitmap的压缩模式(如ARGB_8888和RGB_565)也是控制内存使用的重要手段。 8. 占位符和加载动画:在图片加载期间,可以显示占位符或加载动画,提升用户体验。这可以通过设置默认...

    Android应用源码之android端用于异步加载图片

    例如,及时释放不再使用的Bitmap对象,使用合适的Bitmap.Config(如ARGB_8888或RGB_565),以及合理设置图片的解码尺寸。 8. **异步加载的挑战**: - 滑动列表时,图片的加载和显示需要与滚动同步,避免出现图片...

    Android Bitmap 处理示例

    在Android开发中,Bitmap是用于表示图像数据的核心类,它在UI显示和图像处理中扮演着重要角色。然而,由于Bitmap对象通常占用大量的内存,不当的处理可能导致内存溢出(Out Of Memory)问题,因此对Bitmap进行高效...

    Android上解析24位深度Bitmap文件示例

    综上所述,处理Android上的24位深度Bitmap文件涉及多个层次的优化,包括内存管理、解码策略、异步加载、缓存策略以及颜色处理等。在实际开发中,要根据应用的需求和设备性能选择合适的方法,确保应用运行流畅且资源...

    Android应用源码之图片下载以及内存处理防OOM.zip

    本资料包“Android应用源码之图片下载以及内存处理防OOM.zip”聚焦于解决这些问题,通过源码分析,帮助开发者深入理解如何优化图片处理和内存管理。 1. 图片下载: - 使用异步下载:为避免阻塞UI线程,通常使用...

Global site tag (gtag.js) - Google Analytics