本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!

在适配的过程中,有时我们会用到屏幕宽高,那么如何获得屏幕的分辨率?

方法有两种:

第一种是通过WindowManager接口获得Diaplay对象,通过Display对象来获得

WindowManager manager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

 Display display = manager.getDefaultDisplay();

DisplayMetrics  outMetrics=new DisplayMetrics();

 display.getMetrics(outMetrics);

screenHeight = outMetrics.heightPixels;

screenWidth = outMetrics.widthPixels;

 //screenHeight = display.getHeight();此种方法已废弃

//screenWidth = display.getWidth();此种方法已废弃

或者

从源码上来看,拿height来说:

private final Point mTmpPoint = new Point();

    public int getHeight() {
synchronized (mTmpPoint) {
long now = SystemClock.uptimeMillis();
if (now > (mLastGetTime+20)) {
getSizeInternal(mTmpPoint, true);
mLastGetTime = now;
}
return mTmpPoint.y;
}
}

主要是找mTmpPoint 的y坐标

    private void getSizeInternal(Point outSize, boolean doCompat) {
try {
IWindowManager wm = getWindowManager();
if (wm != null) {
wm.getDisplaySize(outSize);
CompatibilityInfo ci;
if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) {
synchronized (mTmpMetrics) {
mTmpMetrics.noncompatWidthPixels = outSize.x;
mTmpMetrics.noncompatHeightPixels = outSize.y;
mTmpMetrics.density = mDensity;
ci.applyToDisplayMetrics(mTmpMetrics);
outSize.x = mTmpMetrics.widthPixels;
outSize.y = mTmpMetrics.heightPixels;
}
}
} else {
// This is just for boot-strapping, initializing the
// system process before the window manager is up.
outSize.x = getRawWidth();
outSize.y = getRawHeight();
}
if (false) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG, "Returning display size: " + outSize, here);
}
if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v(
TAG, "Returning display size: " + outSize);
} catch (RemoteException e) {
Slog.w("Display", "Unable to get display size", e);
}
}

然后我们发现通过CompatibilityInfo对象设置metrics是一种方法,另一种是getRawHeight()

    public int getRawHeight() {
int h = getRawHeightNative();
if (DEBUG_DISPLAY_SIZE) Slog.v(
TAG, "Returning raw display height: " + h);
return h;
}
private native int getRawHeightNative();

最终是一native方法,通过底层实现。

方法二:通过Resource对象来获得DisplayMetrics来取得

DisplayMetrics metrics = context.getResources().getDisplayMetrics();

screenHeight = metrics.heightPixels;

screenWidth = metrics.widthPixels;

总体来说,都是要取得DisplayMetrics,那么我们来看看它的构成:

    /**
* Standard quantized DPI for low-density screens.
*/
public static final int DENSITY_LOW = 120; /**
* Standard quantized DPI for medium-density screens.
*/
public static final int DENSITY_MEDIUM = 160; /**
* Standard quantized DPI for 720p TV screens. Applications should
* generally not worry about this density, instead targeting
* {@link #DENSITY_XHIGH} for 1080p TV screens. For situations where
* output is needed for a 720p screen, the UI elements can be scaled
* automatically by the platform.
*/
public static final int DENSITY_TV = 213; /**
* Standard quantized DPI for high-density screens.
*/
public static final int DENSITY_HIGH = 240; /**
* Standard quantized DPI for extra-high-density screens.
*/
public static final int DENSITY_XHIGH = 320;

分别有默认的Density值

默认实现方法:

    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 = 0;
noncompatHeightPixels = 0;
}

一般都要实现下面方面,来获得想要的值

    public void setTo(DisplayMetrics o) {
widthPixels = o.widthPixels;
heightPixels = o.heightPixels;
density = o.density;
densityDpi = o.densityDpi;
scaledDensity = o.scaledDensity;
xdpi = o.xdpi;
ydpi = o.ydpi;
noncompatWidthPixels = o.noncompatWidthPixels;
noncompatHeightPixels = o.noncompatHeightPixels;
noncompatDensity = o.noncompatDensity;
noncompatScaledDensity = o.noncompatScaledDensity;
noncompatXdpi = o.noncompatXdpi;
noncompatYdpi = o.noncompatYdpi;
}

看下Resource类

    public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config, CompatibilityInfo compInfo) {
mAssets = assets;
mMetrics.setToDefaults();
mCompatibilityInfo = compInfo;
updateConfiguration(config, metrics);
assets.ensureStringBlocks();
}

看到updateConfiguration(config, metrics);方法

    /**
* Store the newly updated configuration.
*/
public void updateConfiguration(Configuration config,
DisplayMetrics metrics) {
updateConfiguration(config, metrics, null);
}
    /**
* @hide
*/
public void updateConfiguration(Configuration config,
DisplayMetrics metrics, CompatibilityInfo compat) {
synchronized (mTmpValue) {
if (false) {
Slog.i(TAG, "**** Updating config of " + this + ": old config is "
+ mConfiguration + " old compat is " + mCompatibilityInfo);
Slog.i(TAG, "**** Updating config of " + this + ": new config is "
+ config + " new compat is " + compat);
}
if (compat != null) {
mCompatibilityInfo = compat;
}
if (metrics != null) {
mMetrics.setTo(metrics);
}

我们会看到这样的结果,所以在形成Resources的时候,metrics已经写入。

可是刚才我们用的是this.getResouces直接来获得的Resource对象

ContextThemeWrapper:

    @Override
public Resources getResources() {
if (mResources != null) {
return mResources;
}
if (mOverrideConfiguration == null) {
mResources = super.getResources();
return mResources;
} else {
Context resc = createConfigurationContext(mOverrideConfiguration);
mResources = resc.getResources();
return mResources;
}
}

主要是在Context里实现,具体怎么实现,估计还是要看native的代码才知道。

屏幕分辨率的问题就先介绍到这儿。

Android屏幕分辨率获取方法--源码剖析的更多相关文章

  1. java线程基础巩固---线程生命周期以及start方法源码剖析

    上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整 ...

  2. Android屏幕亮度调节相关源码

    如下代码内容是关于Android屏幕亮度调节相关的代码. public static boolean isAutoBrightness(ContentResolver aContentResolver ...

  3. 并发编程之 ConcurrentLinkedQueue 源码剖析

    前言 今天我们继续分析 java 并发包的源码,今天的主角是谁呢?ConcurrentLinkedQueue,上次我们分析了并发下 ArrayList 的替代 CopyOnWriteArrayList ...

  4. 并发编程之 ThreadLocal 源码剖析

    前言 首先看看 JDK 文档的描述: 该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局 ...

  5. Android源码剖析之Framework层升级版(窗口、系统启动)

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 看本篇文章之前,建议先查看: Android源码剖析之Framework层基础版 前面讲了frame ...

  6. 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用

    老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用   上一节我们描述了monkey的命令处理入口函数run是如何调用optionP ...

  7. 玩转Android之Picasso使用详详详详详详解,从入门到源码剖析!!!!

    Picasso是Squareup公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写.如 ...

  8. 老李推荐:第6章2节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-获取命令字串

    老李推荐:第6章2节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-获取命令字串   从上一节的描述可以知道,MonkeyRunner发送给Monkey的命令 ...

  9. 老李推荐:第5章7节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles

    老李推荐:第5章7节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles   poptest是国内唯一一家培养测试开 ...

随机推荐

  1. iOS开发——导入c文件引起的 Unknown type name 'NSString' 错误

    一般情况下出现“Unknown type name”是头文件互相引用出现的,这里不是这个,由于源码使用是c\c++与oc混编,下面三种可以解决问题方案. 解决方案一: 选择所有.c文件,将属性的 id ...

  2. [洛谷P1939]【模板】矩阵加速(数列)

    题目大意:给你一个数列a,规定$a[1]=a[2]=a[3]=1$,$a[i]=a[i-1]+a[i-3](i>3)$求$a[n]\ mod\ 10^9+7$的值. 解题思路:这题看似是很简单的 ...

  3. shell单引号屏蔽变量方法

    [goforit ~]$ name="玖零後大叔" [goforit~]$ echo $name 玖零後大叔 [goforit ~]$ echo "$name" ...

  4. Linux-批量添加用户stu01..stu03,并设置固定的密码123456 (要求不能使用循环for while)

    最终目标: useradd stu01;echo 123456|passwd --stdin stu01 useradd stu02;echo 123456|passwd --stdin stu02 ...

  5. h5调用底层接口的一些知识

    之前接触过这方面的知识,一直想写一些关于代码的文字,但考虑到浪费时间,又不具备大神的实力,也不想去把别人的代码照搬过来,所以一直都是空白着的,今天敲代码的时候,有了一个比较好的想法,第一,定位在学习这 ...

  6. LiquiBase注释

    LiquiBase的注释 <createTable tableName="Role_" remarks="角色表">             < ...

  7. HDU 5438 Ponds dfs模拟

    2015 ACM/ICPC Asia Regional Changchun Online 题意:n个池塘,删掉度数小于2的池塘,输出池塘数为奇数的连通块的池塘容量之和. 思路:两个dfs模拟就行了 # ...

  8. OpenCV中Mat数据的访问报错

    最近再写一段程序的时候,要访问Mat中的元素.在定义Mat型数据的时候,用 Mat ObjectPoints(48,3,CV_32FC1,0) 对其进行初始化后,用at进行访问时报内存错误. Mat ...

  9. 清空/var/adm/wtmp 文件内容

    清/var/adm/wtmp 文件内容 用于显示登录系统和重启机器的情况 /var/adm/wtmp文件过大. 可用du -sm /var/adm/wtmp查看 cat /dev/null>/v ...

  10. 海思平台服务器版软件V15.2产品发布

    深度操作系统海思平台服务器版软件是武汉深之度科技有限公司发布的针对华为海思平台的TaiShan系列服务器发布的企业级服务器操作系统软件产品,主要面向企业级服务器应用场景,为用户在国产化平台上提供更具可 ...