本文来自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. 用VUE做网站后台

    介绍: 这是一个用vuejs2.0和element搭建的后台管理界面. 相关技术: vuejs2.0:渐进式JavaScript框架,易用.灵活.高效,似乎任何规模的应用都适用. element:基于 ...

  2. JDBC连接ORACLE无法登陆java.sql.SQLException: ORA-01017: invalid username/password; logon denied

    当用jdbc连接Oracle数据库的时候 private Connection getConnection() throws SQLException { OracleDataSource ods = ...

  3. mysql主从同步错误恢复

    Mysql主从同步集群在生成环境使用过程中,如果主从服务器之间网络通信条件差或者数据库数据量非常大,容易导致MYSQL主从同步延迟. MYSQL主从产生延迟之后,一旦主库宕机,会导致部分数据没有及时同 ...

  4. Linux 基础入门二

    1.远程连接  ssh协议:secure shell  ~]# ss -tnl 查看系统是否监听在tcp协议的22号接口:  ~]# ip addr list 或者 ifconfig 查看ip地址 确 ...

  5. neo4j nosql图数据库学习

    neo4j 文档:https://neo4j.com/docs/getting-started/current/cypher-intro/ 1.索引 # 给某类标签节点的属性添加索引 CREATE I ...

  6. Kinect for Windows V2 SDK+ VS2012 环境搭建

    眼下使用的SDK版本号是KinectSDK-v2.0-PublicPreview1409-Setup.exe. 下载地址:http://www.microsoft.com/en-us/download ...

  7. 鸟哥的Linux私房菜-----15、例行性命令at与crontab

  8. CAShapeLayer的简单介绍以及基本使用

    1.CAShapeLayer简单介绍  1.1CAShapeLayer继承于CALayer,能够使用CALayer的全部属性值:    1.2CAShapeLayer须要贝塞尔曲线配合使用才有意义(也 ...

  9. 123.static静态函数与类模板

    #include <iostream> using namespace std; //静态函数没有this指针,无需创建对象就可以直接调用 template<class T> ...

  10. Web API总结

    1.Web API 控制器(Controller) 继承ApiController 2. Api 的 Url Map: api/{controller}/{id} 每个"Action&quo ...