本文来自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. 临时的js方法

    //楼层的js var scroChange; //楼层跳转 function FloorGo(domId){//传入目标的id clearInterval(scroChange); var scro ...

  2. RC Immix

    目录 RC Immix 目的 合并型引用计数 伪代码 优点和缺点 合并型引用计数法和Immix的融合 新对象 被动的碎片整理 积极的碎片整理 优点和缺点 优点 缺点 RC Immix Rifat Sh ...

  3. gcc 生成动态链接库

    http://blog.csdn.net/ngvjai/article/details/8520840 Linux下文件的类型是不依赖于其后缀名的,但一般来讲: .o,是目标文件,相当于windows ...

  4. qt 闰年

    bool QDate::isLeapYear ( int year ) [static]

  5. 国庆 day 6 下午

    1.数组异或 (xorarray.pas/c/cpp) (xorarray.in/out) 时间限制:2s/空间限制:256M [题目描述] xor——异或,和 and 与or 一样,是一种重要的逻辑 ...

  6. AJAX--XMLHttpRequest五步使使用方法

    传统浏览方式和AJAX方式的不同 多数Web应用程序都使用请求/响应模型从server上获得完整的HTML页面.经常是点击一个button,等待server对应,在点击还有一个button.然后在等待 ...

  7. cocos2d-x 3.0正式版 vs2013配置

    cocos2d-x 3.0正式版与之前的版本号差异较大,曾经的教程非常多都不使用了. 1.从cocos2d-x官网http://www.cocos2d-x.org下载3.0版的压缩包,随便解压一个位置 ...

  8. 动态网页爬取样例(WebCollector+selenium+phantomjs)

    目标:动态网页爬取 说明:这里的动态网页指几种可能:1)须要用户交互,如常见的登录操作:2)网页通过JS / AJAX动态生成.如一个html里有<div id="test" ...

  9. 22.IntelliJ IDEA 切换 project

    转自:https://blog.csdn.net/qwdafedv/article/details/73838628?utm_source=blogxgwz0 1.file->open 2.选择 ...

  10. POJ 3181完全背包(+高精)

    思路: f[i]表示还剩i空间的方案数 套个高精 (网上有人把它拆成了两个long long) 其实这道题的高精并不难写-.. //By SiriusRen #include <cstdio&g ...