Android屏幕分辨率获取方法--源码剖析

来源:互联网 发布:联想固态硬盘优化软件 编辑:程序博客网 时间:2024/06/05 15:47

                    

                                 本文来自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的代码才知道。

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



0 0
原创粉丝点击