当前位置:首页 > > 充电吧
[导读]    Android设备碎片化问题一直被开发者广为诟病,而且,因为目前手机屏幕越来越来,分辨率越来越高,大有愈演愈烈的趋势。除了等待Google给出一个更加有效的解决方案以外,我们只能尽量适应当前的

    Android设备碎片化问题一直被开发者广为诟病,而且,因为目前手机屏幕越来越来,分辨率越来越高,大有愈演愈烈的趋势。除了等待Google给出一个更加有效的解决方案以外,我们只能尽量适应当前的环境,尽量让自己的产品能够在更多的产品上正常运行。


    在Google的建议下,开发者普遍使用dpi/dp单位,进行UI设计。本文将会介绍dalvik基于dpi加载资源的规则。


DPI

    DPI,全称 dots per inch,意为每英寸的直线上像素点的数量。dpi越高,屏幕的画面越清晰,画质越细腻。

    目前的Android设备支持以下几种DPI:

类别 dpi 缩放比率 代表机型 LDPI 120 75% 已经被市场淘汰 MDPI 160 100% 基本被市场淘汰 TVDPI 213 133% Google Nexus 7 HDPI 240 150% Sumsong Glaxy S2, Google Nexus S, MOTO Droid XHDPI 320 200% Sumsong Glaxy S3, Sumsong Note2, Google Nexus 4 XXHDPI 480 300% 目前市场上各品牌的旗舰机:Sumsong Glaxy S4、 Asus Padfone Infinite、HTC One、 小米3

    上面表格中dpi又称归一化DPI,可以算是一种“理想化”的DPI标准。

    以Eclipse新建Android项目默认提供的机器人ICON为例:

    在drwable-hdpi的文件夹中,ic_launcher.png的size为72*72,而drawable-xhdpi文件夹中的ic_launcher.png的size为96*96。

    理论上来说,在Sumsong Note2(5.5寸,1280*700,XHDPI)上,会加载drawable-xhdpi中的ic_launcher.png,96/320=0.3,使用者会看到一个0.3*0.3英寸的机器人ICON,而在Sumsong的Glaxy S2上(4.3寸,480*800,HDPI)上,会加载drawable-hdpi中到ic_launcher.png,72/240=0.3,使用者仍旧会看到一个0.3*0.3英寸的机器人ICON。所以,从结果上来说,使用者在不同的设备上得到了相同到UI效果,而且,因为在Note2上使用了96*96的ICON, 可以获得更加精细的画面,这似乎是个很理想到结果:即维持了体验的一致性,又最大化的利用了屏幕的显示效果。

    但是,理论和实际总是会有些微妙的差别。设备制造厂商为了迎合消费者的喜好,会生产各种屏幕尺寸的设备,而Android的归一化DPI只有6种(其中2种还是被市场淘汰的),最终呈现给开发者的结果就是,硬件设备的物理dpi(或者说ppi,pixel per inch)总是或大或小,和归一化dpi有一定差距,厂商会根据自己的需要设定设备的归一化DPI,而dalvik进而根据这个归一化DPI来加载资源,绘制界面。

    Note2的物理分辨率其实是267ppi(其实,更接近HDPI,而非XHDPI),而非dalvik认为的320,96/267=0.36,所以,使用者实际看到的是一个0.36*0.36的ICON,而S2的物理分辨率是219,72/219=0.33,所以使用者实际看到的ICON为0.33*0.33寸。所以,界面的实际效果会和开发者的预想有一定偏差。

    幸运的是,只要设备制造商设定的归一化DPI和设备的物理分辨率差距不会大的离谱(想象一下,DPI设置不佳导致大部分app都无法正常运行的设备,能够大卖么?),界面的最终效果还是能够达到开发者的要求的。


基于DPI的资源加载优先级

    首先,我们需要明白dalvik匹配最佳资源的策略,从Google的官方资料,我们可以知道dalvik是这样工作的:

根据设备的属性,排除所有存在冲突属性的资源,注意两点: 不对Screen pixel density & screen size两个属性做检查如果在这一步就排除了所有资源,则抛出ResourceNotFoundException挑选当前优先级最高的属性 属性的优先级排序为:MCC and MNC、 Language and region、 Layout Direction、 smallestWidth、 Aailable width、 Aailable height、 Screen size、 Screen aspect、 Screen orientation、 UI mode、 Night Mode、 Screen pixel density(dpi)、 Touchscreen type、 Keyboard availability、 Primary test input method、 Navigation key availability、 Primary non-touch navigation method、 Platform Version如果存在包含了当前属性的资源,则执行4,否则跳过当前属性,执行2排除所有不包含该属性的资源 如果当前属性为screnn pixel density,则以如下方式进行匹配: 如果有最匹配的资源(e.g. 设备是HDPI,存在hdpi的资源),则删除其他的资源如果没有最佳匹配资源,优先匹配更高dpi的资源,缩小合适的比例以后使用(e.g. 设备是HDPI,未能找到hdpi的资源,但是有xhdpi的资源,则把XHDPI的资源缩小的3/4以后使用),并排除其他的资源(Google解释说,因为执行缩小操作比执行放大操作更加方便,所以高dpi资源优先与低dpi资源,不过,个人认为对于大部分图片来说,大图缩小造成的失真应该是小于小图放大造成的失真)如果没最佳匹配的资源,也不存在更高dpi的资源,则使用dpi更低的资源,并放大合适的比例以后使用(e.g. 设备为HDPI,未能找到hdpi以及更高的资源,单存在mdpi的资源,则把mdpi的资源放大到3/2以后使用),并删排除其他资源如果当前性为screen size,则以如下方式进行匹配: 如果有最佳匹配资源(e.g. 设备为large,存在large的资源),则排除其他资源如果没有最佳匹配资源,则使用更小size的资源(e.g. 设备为large,但是存在normal资源,则使用normal资源),排除其他资源如果没有最佳匹配资源,也没有更小size的资源,则抛出ResourceNotFoundException是否仅剩余唯一的资源,是则执行6,否则执行2以唯一的资源为最佳资源,匹配结束

    从Google的资料中,我们可以知道dalvik匹配最佳资源的逻辑,但是还有四个问题未解释清楚:

当最佳dpi资源不存在,但是高dpi资源大于一个时(e.g. 设备为hdpi,但是apk仅提供xhdpi & xxhdpi资源),如何选择资源?当最佳dpi资源&高dpi资源都不存在,但是低dpi资源大于1个时(e.g. 设备为hdpi,但是apk仅提供mdpi & ldpi资源),如何选择资源?当drawable资源不包含screen pixel density(e.g. 文件夹名为”drawable“,下文中称之为default)属性时,如何选择资源?当资源被nodpi修饰时,如何选择资源?

    既然没有现成的资料,就让我们自己测试:

测试设备:Nexus 7(TVDPI)

测试代码:



	


    仅在Layout根目录添加了一个ImageView,未修改Eclipse自动生成的java代码。

测试图片:rabit.png, size:600*450pixel

问题1:

仅提供XHDPI & XXHDPI两种资源:


运行结果:


从执行结果,我们可以看到,dalvik使用了xhdpi的资源,并且进行了合适的缩小:600*1.33/2=399,450*1.33/2=299.

结论:当最佳dpi资源不存在,而高dpi资源大于1个时,选择更接近设备的资源(即较低dpi的资源),并根据缩放比缩小合适的比例后使用。

问题2:

仅提供ldpi和mdpi两种资源:


运行结果:


从运行结果,我们可以知道davlik加载了mdpi,并放大了合适的倍数:450*1.33/1 = 599(因为这里图片水平方向上已经被截断少许,所以未测量)。

结论:当最佳dpi资源&高dpi资源都不存在,而且dpi资源大于1个时,选择更接近设备的低dpi资源,并根据缩放比放大合适的比例后使用。

问题三:

第一步测试:

仅提供mdpi,ldpi,default三种资源:


运行结果:


从运行结果来看,mdpi资源的优先级要高于default。

第二步测试:

在第一步的基础上,删除mdpi下的rabit.png:


运行结果:


从运行结果看,default的优先级高于ldpi。

另外,我们可以看到default的缩放比和mdpi是一致的,由此我猜测,因为Android是以mdpi作为dpi基准,所以,default等同与mdpi,但是,资源优先级而言mdpi高于default。根据这个猜测,对于ldpi的设备来说,优先级顺序会是这样的:ldpi>mdpi>default>hdpi,不过找不到ldpi的设备,也无法验证。

结论:对于高于hdpi(包括hdpi)的设备来说,default资源的优先级高于ldpi但是低于mdpi,并且缩放比等于mdpi。

问题4:

步骤1,仅提供ldpi和nodpi的资源:


运行结果:


从运行结果来看,ldpi的优先级高于nodpi。

步骤2,在步骤1的基础上删除ldpi的资源:


运行结果:


从运行结果,我们看到,图片的确如google官方资料所说,未经过任何缩放。不过,google提供nodpi似乎是非常的不愿意啊,优先级最低,仅在无图可用的情况下,才会使用nodpi的资源。


结论

原则上来说,dalvik优先使用符合设备dpi的资源,其次是dpi较低的高dpi资源,再次是dpi较高的高dpi资源,最后采用nodpi的资源,由此,根据设备自身的dpi的不同,不同dpi资源的优先级是有差异的(忽略mdpi&hdpi):

设备dpi 优先级顺序(由高到低) tvdpi tvdpi>hdpi>xhdpi>xxhdpi>mdpi>default>ldpi>nodpi hdpi hdpi>xhdpi>xxhdpi>tvdpi>mdpi>default>ldpi>nodpi xhdpi xhdpi>xxhdpi>hdpi>tvdpi>mdpi>default>ldpi>nodpi xxhdpi xxhdpi>xhdpi>hdpi>tvdpi>mdpi>default>ldpi>nodpi 另外,除了nodpi以外,使用其他dpi资源前,还需要根据缩放比进行缩小/放大操作。

    经过同事的测试,上面的结论有一点小问题:

    hdpi的设备对于dpi的优先级顺序实际上是这样的: hdpi>tvdpi>xhdpi>xxhdpi>>mdpi>default>ldpi>nodpi(可能Google觉得tvdpi(213)还是很接近hdpi(240)的,可堪一用)


参考资料:

http://developer.android.com/guide/topics/resources/providing-resources.html

http://developer.android.com/guide/practices/screens_support.html

http://ivan-ru.iteye.com/blog/1711414

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭