安卓面试总结——UI

2019-12-10  本文已影响0人  Alex_ecb1

1.屏幕适配

https://www.jianshu.com/p/7aa34434ad4d

物理尺寸和分辨率

1.屏幕尺寸适配

     1.1布局适配

         使用相对布局

    1.2根据屏幕的配置来加载相应的UI布局

         最小宽度(Smallest-width)限定符

         屏幕方向(Orientation)限定符。

         使用限定符。通过配置限定符使得程序在运行时根据当前设备的配置加载不同布局

          不同布局通过布局别名区分

     1.3.布局组件适配

         使得布局组件自适应屏幕尺寸。

         图片资源匹配 使用自动拉伸位图  .9.png

     1.4.用户界面流程适配

          先通过value中的配置信息确认现在处于什么模式

 2. 屏幕密度适配

         使用 密度无关像素 ( dp ) 或 独立比例像素( sp ) 作为计量单位。 没有解决设备 尺寸大小匹配 的问题    

         以某一分辨率为基准,生成所有分辨率对应像素数列表

2.bitmap大小

要选择合适的图片规格,因为不同规格的图片所占用的内存不同

ALPHA_8 每个像素占用1byte内存

ARGB_4444 每个像素占用2byte内存

ARGB_8888 每个像素占用4byte内存(默认)

RGB_565 每个像素占用2byte内存

图片压缩。通过BitmapFactory对图片进行压缩,这样就会降低内存占用从而在一定程度上避免OOM,提高Bitmap加载时的性能。

复用内存。通过软引用(内存不够的时候才会回收掉)来复用内存块,就不需要再重新给这个bitmap申请一块新的内存,避免了一次内存的分配和回收带来的性能消耗。

整个Bitmap,包括数据和引用,都放在了堆中,这样,整个Bitmap的回收就全部交给GC了,这个recycle方法就再也不需要使用了。

我们用createBitmap创建的Bitmap且没有被硬件加速Canvas draw过,则主动调用recycle产生的意义比较小,仅释放了native里的SkPixelRef的内存,这种情况我觉得可以不主动调用recycle。

被硬件加速Canvas draw过的由于有TextureCache应该尽快调用recycle来尽早释放其TextureCache。

大图片加载

https://www.jianshu.com/p/37007f685fe9

3.listview优化

ListView的复用机制是ListView为了提高效率内部实现的一种优化,这种优化是通过复用itemview的方式实现的。

它是怎么提高效率的呢?

对于一个Listview来说,往往有很多的itemview,如果每次在获取itemview的时候都通过重新创建的方式去获取势必会影响效率,尤其是在用户频繁滑动的情况下。通过复用之前创建过的itemView就可以避免重复创建,从而提升效率。

遇到过ListView异步加载图片乱序的问题吗?它的原因是什么?最后是怎么解决的?

遇到过。把获取到的图片放于itemview中,然后不断的滑动listview时,由于listview的复用机制,它会把之前的view复用到滑动到的新的view上,这就会造成图片错位,同时它还在异步获取新的图片,这就会造成滑动时itemview上图片的变换。

解决方法是使用findViewWithTag,由于ListView中的ImageView控件都是重用的,移出屏幕的控件很快会被进入屏幕的图片重新利用起来,那么getView()方法就会再次得到执行,而在getView()方法中会为这个ImageView控件设置新的Tag,这样老的Tag就会被覆盖掉,于是这时再调用findVIewWithTag()方法并传入老的Tag,就只能得到null了,而我们判断只有ImageView不等于null的时候才会设置图片,这样图片乱序的问题也就不存在了。

4.TouchDelegate 扩大按钮响应区域

https://www.jianshu.com/p/ce14c7d96b0c

5.viewstub

https://www.jianshu.com/p/9f2e7cf9a0b4

宽高都为0,通过inflate加载

6.Bitmap

如何计算一个Bitmap占用内存的大小,怎么保证加载Bitmap不产生内存溢出?

Bitamp 占用内存大小 = 宽度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一个像素所占的内存.

注:这里inDensity表示目标图片的dpi(放在哪个资源文件夹下),inTargetDensity表示目标屏幕的dpi,所以你可以发现inDensity和inTargetDensity会对Bitmap的宽高

进行拉伸,进而改变Bitmap占用内存的大小。

在Bitmap里有两个获取内存占用大小的方法。

getByteCount():API12 加入,代表存储 Bitmap 的像素需要的最少内存。

getAllocationByteCount():API19 加入,代表在内存中为 Bitmap 分配的内存大小,代替了 getByteCount() 方法。

在不复用 Bitmap 时,getByteCount() 和 getAllocationByteCount 返回的结果是一样的。在通过复用 Bitmap 来解码图片时,那么 getByteCount() 表示新解码图片占用内存的大

小,getAllocationByteCount() 表示被复用 Bitmap真实占用的内存大小(即 mBuffer 的长度)。

为了保证在加载Bitmap的时候不产生内存溢出,可以受用BitmapFactory进行图片压缩,主要有以下几个参数:

BitmapFactory.Options.inPreferredConfig:将ARGB_8888改为RGB_565,改变编码方式,节约内存。

BitmapFactory.Options.inSampleSize:缩放比例,可以参考Luban那个库,根据图片宽高计算出合适的缩放比例。

BitmapFactory.Options.inPurgeable:让系统可以内存不足时回收内存。

上一篇 下一篇

猜你喜欢

热点阅读