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

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

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. [分享] 封装工具ES4配置文件解释

    [分享] 封装工具ES4配置文件解释 LiQiang 发表于 2015-2-3 14:41:21 https://www.itsk.com/thread-346132-1-4.html [分享] 封装 ...

  2. 数据库 MySQL安装图解

    MySQL安装图解 一.MYSQL的安装 1.打开下载的mysql安装文件,双击运行mysql-5.5.40-win32.msi. 2.选择安装类型,有"Typical(默认)". ...

  3. 使用Memcache缓存mysql数据库操作的原理和缓存过程浅析

    转载自脚本之家 http://www.jb51.net/article/51831.htm  作者:忙碌的松鼠 对于大型网站如facebook,ebay等网站,如果没有Memcache做为中间缓存层, ...

  4. Centos7下配置Redis开机自启动

    最近在做作业的时候需要用到Redis缓存,由于每次重启服务器都需要重新启动Redis,也是忒烦人,于是就有了这一篇博客,好,废话不多说. 只有两个步骤: 设置redis.conf中daemonize为 ...

  5. 查找数组中重复项的index

    var ary = [5, 4, 4, 2, 7, 8, 33, 2222, 99, 88]; function isRepeat(arr) { var hash = {}; for (var i=0 ...

  6. VC++使用Pro*CC++

    几种数据库访问技术的比较 由上所述, Visual C++ 通过以上方法都可以访问Oracle 数据 库, 但是上述方法各有优缺点.ODBC 出现得比较早, 几乎支持所 有的关系型数据库, 而且有MF ...

  7. biweb后台添加上传下载功能

    1.数据库对应表添加字段 file       varchar(100) 2.对应的后台 模块名/admin/addinfo.php里添加如下代码: //文件上传 if ((($_FILES[&quo ...

  8. webservice 实现json模式

    直接上代码 public string GetUserInfoByOpenid(string openid) { var weixinuser = new WeiXinUser(); weixinus ...

  9. 浏览器主页被hao123贱贱的篡改的一种方式

    今天打开一个PDF文件(正经文件,不要想歪了),误点了一个“编辑”按钮,出来发现浏览器主页被篡改了,包括chrome和IE.通过一个网址"www.qquuu8.com"跳转到hao ...

  10. 汽车驱动之家 http://bmw360.cn

    汽车驱动之家 http://bmw360.cn