记一次更改为了适配盒子,修改了盒子系统density值的过程

1. 背景

因为项目需要,需要把我在一个A盒子上写的Launcher App,移植到B盒子上,唯一的要求就是快。

A盒子和B盒子都是1080PUI.

2. 遇到问题And找解决方法

我简单挪过去了后发现,屏幕显示不对,经过我自己分析,发现,A盒子上1dp=2px,而B盒子上1dp=1.5px,

我们做Android的都知道,densityDpi/160就是dp和px的比例,也就是density。而在Android里得到density:

density=context.getResources().getDisplayMetrics().density;

于是我就查看源码:

/**
     * Return the current display metrics that are in effect for this resource 
     * object.  The returned object should be treated as read-only.
     * 
     * @return The resource's current display metrics. 
     */
    public DisplayMetrics getDisplayMetrics() {
        return mResourcesImpl.getDisplayMetrics();
    }

再往里跟

DisplayMetrics getDisplayMetrics() {
        if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels
                + "x" + mMetrics.heightPixels + " " + mMetrics.density);
        return mMetrics;
    }

发现了直接返回的是mMetrics,而mMetrics是如何初始画的呢,发现:

private final DisplayMetrics mMetrics = new 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;
    }

以上是DisplayMetrics.java中的代码,随便说一句,是Android 7.0的

仔细看

densityDpi =  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));
}

看到这里,我们知道了,我只要把属性ro.sf.lcd_density改成320就完全不需要修改任何代码,我们的Launcher就能适配到B盒子上。

3. 解决

这里有两总解决方案,第一种,adb shell进去 wm density 320 搞定。

第二种,改Physical density

通过2阶段的分析,我们知道,我们只要把ro.sf.lcd_density 改了就可以

所以我们adb shell进去

然后 getprop |grep density

记一次更改为了适配盒子,修改了盒子系统density值的过程

(这里显示的320是我已经改过的。改之前是240)

当时一看,两个值都是240,所以我就吧system/build.prop 拿出来,修改了ro.sf.lcd_density 的值,然后adb remount 

然后 adb push 把build.prop放回到原来位置。使用setprop persist.sys.screen_density 320 命令把persist.sys.screen_density也改

成了320, 然后 sync 。reboot

机器重启后,发现界面果然正常了,但是竟然出现了虚拟Home键。

记一次更改为了适配盒子,修改了盒子系统density值的过程

而我们知道在build.prop中qemu.hw.mainkeys属性为0表示打开虚拟见,而为1表示隐藏虚拟键,所以在此把/system/build.prop拿出来,改了这个属性值,重启机器。Ok。解决。

 

记一次更改为了适配盒子,修改了盒子系统density值的过程

已经没有了虚拟按键

上一篇:Fibonacci数列通项公式


下一篇:java将JSON字符串转换为实体类对象,基于net sf json实现