---恢复内容开始---

今天做屏幕适配的时候,发现一个奇怪的现象:

HTC D820u/ 红米Note/HONOR H30-L02 /Coolpad 8297-T01 4款手机的分辨率均为 1280 * 720,但是得到的densityDpi

都是320,这跌破了我一直以来的观点(densityDpi = 屏幕对角线的像素值/对角线的尺寸)。像素值是一样的,但尺寸明显是不一样的,

densityDpi 怎么可能一样?

 我们知道 dpi (dots per inch 每英寸像素数) 也就是 像素/尺寸 比如 320* 240 分辨率 物理尺寸为2 英寸*1.5英寸

那么dpi = 320/2 = 240/1.5 = 160  像素/英寸,也可以称之为像素密度,而手机像素密度(density)实际上是以单位英寸160个像素作为参考标准的。

再来看看 densityDpi

DisplayMetrics dm  = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
dm.densityDpi 就可以获得密度Dpi

通过查询源码可知:
android.util.DisplayMetrics 类中
public void setToDefaults() {
widthPixels = 0;
heightPixels = 0;
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
densityDpi = DENSITY_DEVICE;
scaledDensity = density;
xdpi = DENSITY_DEVICE;
ydpi = DENSITY_DEVICE;
noncompatWidthPixels = widthPixels;
noncompatHeightPixels = heightPixels;
noncompatDensity = density;
noncompatDensityDpi = densityDpi;
noncompatScaledDensity = scaledDensity;
noncompatXdpi = xdpi;
noncompatYdpi = ydpi;
}

densitDpi 是由DENSITY_DEVICE  赋值的,而 DENSITY_DEVICE 是个常量
public static int DENSITY_DEVICE = getDeviceDensity();
private static int getDeviceDensity() {
// qemu.sf.lcd_density can be used to override ro.sf.lcd_density
// when running in the emulator, allowing for dynamic configurations.
// The reason for this is that ro.sf.lcd_density is write-once and is
// set by the init process when it parses build.prop before anything else.
return SystemProperties.getInt("qemu.sf.lcd_density",
SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
}
qemu.sf.lcd_density 在模拟器中运行时可以用来覆盖ro.sf.lcd_density,允许动态的配置
这么做的理由是:ro.sf.lcd_density 只能被写入一次,由初始化进程在做其他的事之前解析build.prop
时设置。
那就是说densiDpi 默认是从 ro.sf.lcd_density 这个文件读取的。而这个文件
在system/build.prop 内。
adb shell
cd system
cat system/build.prop 可以查看里面的东西,放置的都是一些系统的配置。或者
adb shell getprop ro.sf.lcd_density  直接查看 
果然 默认的就是320。

查阅相关资料 :
http://www.jb51.net/article/33238.htm

提起分辨率,我们需要了解两个概念,图像分辨率和输出分辨率。

图像分辨率是每英寸的像素数,以ppi为单位,图像分辨率又常常被表示成每一个方向上的总像素数量,比如640×480像素、1280×960像素等。而决定图像输出质量的是图像的输出分辨率,描述的是设备输出图像时每英寸可产生的点数(dpi),以dpi为单位,两者有联系但并不总是相等的。

dpi (dot per inch)输出分辨率

打印机分辨率又称为输出分辨率,是指在打印输出时横向和纵向两个方向上每英寸最多能够打印的点数,通常以“点/英寸”即dpi(dot per inch)表示。而所谓最高分辨率就是指打印机所能打印的最大分辨率,也就是所说的打印输出的极限分辨率。平时所说的打印机分辨率一般指打印机的最大分辨率,目前一般激光打印机的分辨率均在600×600dpi以上。

dpi是“dot per inch”的缩写。顾名思义,就是指在每英寸长度内的点数。通常,我们都使用dpi来作为扫描器和打印机的解析度单位,数值越高表示解析度越高。目前,市面上出售扫描器的光学解析度主要有600×1200 dpi和1200×2400 dpi两种。扫描器的光学解析度由两个数字构成,是因为横向解析度和纵向解析度不同。较小的数字通常为纵向解析度,即我们一般区分扫描器解析度用的数值。也就是说,600×1200 dpi的扫描器,我们通常简称为600 dpi。

电脑显示器的解析度约为72dpi,这个数值其实是这样计算出来的:以一部15寸的电脑显示器为例,可视面积的水平长度大约为11.2寸,如果显示模式是800×600,那么解析度就是800/11.2=71.4。如果是17寸电脑显示器,以1024×768的显示模式来看,解析度就变成1024/12.8=80了。

而dpi只是输出分辨率,PPI(Pixels Per Inch)才是图像分辨率,两个根本就不是一个东西。

而android 用dip(dp) 做长度单位时 : pix = dip * (densityDpi / 160) = dip * density , densityDpi = 160 时 density = 1 , pix == dip 。

---恢复内容结束---

android densityDpi 的由来的更多相关文章

  1. Android 权限的由来

    在Android APP开发过程中,某些行为动作需要在AndroidManifest.xml清单文件中进行权限相关的配置: <!-- 增加权限 --> <uses-permissio ...

  2. Android与Unity交互研究

    转载请注明出处:http://blog.csdn.net/crazy1235/article/details/46733221 Android与Unity交互研究 unity与android交互的由来 ...

  3. Android中px dpi dip density densityDpi 的相关说明

    转自:http://www.cnblogs.com/wader2011/archive/2011/11/29/2267490.html 概念解释 名词 解释 Px (Pixel像素) 不同设备显示效果 ...

  4. 转 Android:sp与dp(densityDpi与scaledDensity)

    一般在布局上设置控件大小维度的单位采用dp,而定义字体大小的单位采用sp. dp是dip,density independent pixel,即密度无关的像素单位,说白了,就是这个维度相对于不同屏幕的 ...

  5. [置顶] Android 适配真要命?

    原始尺寸场景 相信大家对上面也有所有耳闻另外就是如何计算屏幕的密度一般都是按照勾股定理例如中等屏幕密度 480^2+800^2开根号 然后除以当前屏幕尺寸3.5-4.2之间尺寸. 对于刚出来的那些An ...

  6. Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手

    图片加载性能优化永远是Android领域中一个无法绕过的话题,经过数年的发展,涌现了很多成熟的图片加载开源库,比如Fresco.Picasso.UIL等等,使得图片加载不再是一个头疼的问题,并且大幅降 ...

  7. Android Weekly Notes Issue #235

    Android Weekly Issue #235 December 11th, 2016 Android Weekly Issue #235 本期内容包括: 开发一个自定义View并发布为开源库的完 ...

  8. Android功能点

    1.获取屏幕尺寸.密度等信息. 1)最常用的方法: WindowManager windowManager = getWindowManager(); Display display = window ...

  9. android开发:深入理解View(一):从setContentView谈起

    我们都知道 MVC,在Android中,这个 V 即指View,那我们今天就来探探View的究竟. 在onCreate方法中,可以调用this.setContentView(layout_id),来设 ...

随机推荐

  1. [hadoop] hadoop-all-in-one-伪分布式安装

    hadoop伪分布式-all-in-one安装 #查看hadoop 版本 [root@hadoop-allinone-200-123 bin]# pwd /wdcloud/app/hadoop-2.7 ...

  2. Java双循环break的用法

    break只跳出当前循环,也就是内循环,如果想跳出外循环有两种办法:1:for(int i = 0;i<9;i++){ //用两个breakfor(int j = 0;j<8;j++){b ...

  3. Unity3D 中的协程

    若干文章: 1.Coroutine,你究竟干了什么? 2.Radical Coroutines 3.Extended Unity Coroutines

  4. Python 修饰符

    def hello(fn):    def wrapper():        print "hello"        fn()        print "goodb ...

  5. Android开发--Android Studio配置

    1.常见问题 emulator: You might want to adjust your AVD RAM size and/or HAXM configuration to run in fast ...

  6. Datafactory必须注意事项

  7. PDF 补丁丁 0.5.0.2078 测试版发布:不用打字,也能加书签

    新增功能: 在书签编辑器加书签,不再需要自己输文本. 书签编辑器的阅读界面增加了识别文本字符的功能,可使用该功能在添加书签时识别文本. 右键点击文本内容,可插入书签(对于扫描版的文档,在激活识别引擎后 ...

  8. phpMyAdmin - 错误 您应升级到 MySQL 5.5.0 或更高版本,解决办法。。。

    折腾自己的个人网站,装了个数据库管理工具,遇到您应升级到 MySQL 5.5.0 或更高版本... 采用降级phpmyadmin版本的方法解决了: 查找phpmyadmin/libraries/com ...

  9. cp命令

    [root@www ~]# cp [-adfilprsu] 来源文件(source) 目标文件(destination) [root@www ~]# cp [options] source1 sour ...

  10. Laravel框架 mysql 数据库 —— 基本使用

    增删改查 配置完数据库连接,就可以使用DB类进行查询了. 查询 $results = DB::select('select * from users where id = ?', array(1)); ...