一.Android多机型适配:

多机型适配在Android开发中经常会碰到,那么如果我们只有一部测试机,如何能做到用这一部手机来看各种不同分辨率手机的UI显示呢!不需要桌前摆一排手机来一个一个的是看。

二.WM命令:

1.什么是WM命令:

说了这么多前提,实际上需要使用的就是一行 wm 命令,可以通过 adb shell 来操作它。

wm 命令主要用来帮助我们修改一些屏幕的参数,先来看看它的文档。使用 adb shell wm 命令,可以方便的查看 wm 的文档描述

可以看到,wm 命令可以帮助我们修改当前设备的 size 、 density 等参数,而这两个参数就是决定了当前设备的显示效果。

2.2 WM命令

上面的文档中有很多命令,其实我们平时用到的一般只有size,density这两个,以下例子为一部1080x1920的设备:

1. wm size命令

wm size 命令,可以用来查询和修改当前设备的尺寸,如果想要修改尺寸,可以使用 px 或者 dp 为单位(默认为 px),使用 x 进行连接,这个其实看看 wm size 的输出,你就清楚了。

上面的例子中,调用了不同的命令:

1.使用 wm size 命令查看当前设备的尺寸。

2.使用 wm size 命令将当前尺寸修改成了 1000x2000。

3.再次使用 wm size 命令查看当前设备的尺寸。

4.最后使用 wm size reset 命令,将屏幕尺寸还原。

5.再用 wm size 命令,查看还原后的尺寸。

这几个步骤就已经涵盖了 wm size 命令的所有使用步骤,可以使用它查看当前屏幕尺寸,并且修改屏幕尺寸和还原它。

2.wm density命令

wm density 命令,可以用来查看和修改当前设备的 density 参数。

使用起来跟wm size相同,我们直接上命令吧。

在这个例子中,我做了几件事情:

1.使用 wm density 查看当前设备的 density。

2.在使用 wm density 命令,修改当前设备的 density 为 560,580。

3.然后再使用 wm density 查看修改后的参数。

4.最后使用 wm density reset 将设备的 density 还原。

5.最后再查看一下还原后的值。

3.wm overscan命令

wm overscan 命令,可以修改当前设备的屏幕内边距。这个命令一般用不到。

在这个例子中,做了两件事:

1.使用 wm overscan 修改边距为 30 。

2.然后使用 wm overscan reset 将其还原。

WM命令源码:

package com.android.commands.wm;
20
21import android.content.Context;
22import android.graphics.Point;
23import android.graphics.Rect;
24import android.os.RemoteException;
25import android.os.ServiceManager;
26import android.os.UserHandle;
27import android.util.AndroidException;
28import android.util.DisplayMetrics;
29import android.view.Display;
30import android.view.IWindowManager;
31import com.android.internal.os.BaseCommand;
32
33import java.io.PrintStream;
34import java.util.regex.Matcher;
35import java.util.regex.Pattern;
36
37public class Wm extends BaseCommand {
38
39    private IWindowManager mWm;
40
41    /**
42     * Command-line entry point.
43     *
44     * @param args The command-line arguments
45     */
46    public static void main(String[] args) {
47        (new Wm()).run(args);
48    }
49
50    @Override
51    public void onShowUsage(PrintStream out) {
52        out.println(
53                "usage: wm [subcommand] [options]\n" +
54                "       wm size [reset|WxH|WdpxHdp]\n" +
55                "       wm density [reset|DENSITY]\n" +
56                "       wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
57                "       wm scaling [off|auto]\n" +
58                "       wm screen-capture [userId] [true|false]\n" +
59                "\n" +
60                "wm size: return or override display size.\n" +
61                "         width and height in pixels unless suffixed with 'dp'.\n" +
62                "\n" +
63                "wm density: override display density.\n" +
64                "\n" +
65                "wm overscan: set overscan area for display.\n" +
66                "\n" +
67                "wm scaling: set display scaling mode.\n" +
68                "\n" +
69                "wm screen-capture: enable/disable screen capture.\n" +
70                "\n" +
71                "wm dismiss-keyguard: dismiss the keyguard, prompting the user for auth if " +
72                "necessary.\n"
73                );
74    }
75
76    @Override
77    public void onRun() throws Exception {
78        mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
79                        Context.WINDOW_SERVICE));
80        if (mWm == null) {
81            System.err.println(NO_SYSTEM_ERROR_CODE);
82            throw new AndroidException("Can't connect to window manager; is the system running?");
83        }
84
85        String op = nextArgRequired();
86
87        if (op.equals("size")) {
88            runDisplaySize();
89        } else if (op.equals("density")) {
90            runDisplayDensity();
91        } else if (op.equals("overscan")) {
92            runDisplayOverscan();
93        } else if (op.equals("scaling")) {
94            runDisplayScaling();
95        } else if (op.equals("screen-capture")) {
96            runSetScreenCapture();
97        } else if (op.equals("dismiss-keyguard")) {
98            runDismissKeyguard();
99        } else {
100            showError("Error: unknown command '" + op + "'");
101            return;
102        }
103    }
104
105    private void runSetScreenCapture() throws Exception {
106        String userIdStr = nextArg();
107        String enableStr = nextArg();
108        int userId;
109        boolean disable;
110
111        try {
112            userId = Integer.parseInt(userIdStr);
113        } catch (NumberFormatException e) {
114            System.err.println("Error: bad number " + e);
115            return;
116        }
117
118        disable = !Boolean.parseBoolean(enableStr);
119
120        try {
121            mWm.setScreenCaptureDisabled(userId, disable);
122        } catch (RemoteException e) {
123            System.err.println("Error: Can't set screen capture " + e);
124        }
125    }
126
127    private void runDisplaySize() throws Exception {
128        String size = nextArg();
129        int w, h;
130        if (size == null) {
131            Point initialSize = new Point();
132            Point baseSize = new Point();
133            try {
134                mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);
135                mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);
136                System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);
137                if (!initialSize.equals(baseSize)) {
138                    System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);
139                }
140            } catch (RemoteException e) {
141            }
142            return;
143        } else if ("reset".equals(size)) {
144            w = h = -1;
145        } else {
146            int div = size.indexOf('x');
147            if (div <= 0 || div >= (size.length()-1)) {
148                System.err.println("Error: bad size " + size);
149                return;
150            }
151            String wstr = size.substring(0, div);
152            String hstr = size.substring(div+1);
153            try {
154                w = parseDimension(wstr);
155                h = parseDimension(hstr);
156            } catch (NumberFormatException e) {
157                System.err.println("Error: bad number " + e);
158                return;
159            }
160        }
161
162        try {
163            if (w >= 0 && h >= 0) {
164                // TODO(multidisplay): For now Configuration only applies to main screen.
165                mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
166            } else {
167                mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
168            }
169        } catch (RemoteException e) {
170        }
171    }
172
173    private void runDisplayDensity() throws Exception {
174        String densityStr = nextArg();
175        int density;
176        if (densityStr == null) {
177            try {
178                int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
179                int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
180                System.out.println("Physical density: " + initialDensity);
181                if (initialDensity != baseDensity) {
182                    System.out.println("Override density: " + baseDensity);
183                }
184            } catch (RemoteException e) {
185            }
186            return;
187        } else if ("reset".equals(densityStr)) {
188            density = -1;
189        } else {
190            try {
191                density = Integer.parseInt(densityStr);
192            } catch (NumberFormatException e) {
193                System.err.println("Error: bad number " + e);
194                return;
195            }
196            if (density < 72) {
197                System.err.println("Error: density must be >= 72");
198                return;
199            }
200        }
201
202        try {
203            if (density > 0) {
204                // TODO(multidisplay): For now Configuration only applies to main screen.
205                mWm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density,
206                        UserHandle.USER_CURRENT);
207            } else {
208                mWm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY,
209                        UserHandle.USER_CURRENT);
210            }
211        } catch (RemoteException e) {
212        }
213    }
214
215    private void runDisplayOverscan() throws Exception {
216        String overscanStr = nextArgRequired();
217        Rect rect = new Rect();
218        if ("reset".equals(overscanStr)) {
219            rect.set(0, 0, 0, 0);
220        } else {
221            final Pattern FLATTENED_PATTERN = Pattern.compile(
222                    "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)");
223            Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr);
224            if (!matcher.matches()) {
225                System.err.println("Error: bad rectangle arg: " + overscanStr);
226                return;
227            }
228            rect.left = Integer.parseInt(matcher.group(1));
229            rect.top = Integer.parseInt(matcher.group(2));
230            rect.right = Integer.parseInt(matcher.group(3));
231            rect.bottom = Integer.parseInt(matcher.group(4));
232        }
233
234        try {
235            mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom);
236        } catch (RemoteException e) {
237        }
238    }
239
240    private void runDisplayScaling() throws Exception {
241        String scalingStr = nextArgRequired();
242        if ("auto".equals(scalingStr)) {
243            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);
244        } else if ("off".equals(scalingStr)) {
245            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
246        } else {
247            System.err.println("Error: scaling must be 'auto' or 'off'");
248        }
249    }
250
251    private void runDismissKeyguard() throws Exception {
252        mWm.dismissKeyguard();
253    }
254
255    private int parseDimension(String s) throws NumberFormatException {
256        if (s.endsWith("px")) {
257            return Integer.parseInt(s.substring(0, s.length() - 2));
258        }
259        if (s.endsWith("dp")) {
260            int density;
261            try {
262                density = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
263            } catch (RemoteException e) {
264                density = DisplayMetrics.DENSITY_DEFAULT;
265            }
266            return Integer.parseInt(s.substring(0, s.length() - 2)) * density /
267                    DisplayMetrics.DENSITY_DEFAULT;
268        }
269        return Integer.parseInt(s);
270    }
271}

根据上述源码以wm size 为例,解析下源码:

1.wm 命令的逻辑非常的简单,它实际上是和 WindowManagerService 进行交互,通过 WMS 来修改屏幕相关的一些参数。

这里就不介绍完整的 wm 源码了,就以一个方法举例来看看 wm 的逻辑。这里就以 wm size 命令举例好了。

首先,看看 wm 命令的入口onRun()。

2.这里会初始化 mWm ,并且根据输入的参数,调用不同的方法,如果输入的是 size ,则会调用 runDisplaySize() 方法。

3.在 runDisplaySize() 方法中,会先判断 size 命令后面有没有跟其它参数,如果没有,则认为是一次查询操作,会将查询到的结果输出。

而如果是 reset 方法的话,就将 w 、h 这两个代表宽高的值,设置为 -1,最终会通过 mWm.clearForcedDisplaySize() 方法,将屏幕的 size 还原。

否者就从输入的参数中,通过 x 进行分割,拿到我们输入的宽高。最终通过 mWm.setForcedDisplaySize() 方法,将当前屏幕的 size 修改成我们输入的结果。

在设置size 的时候,还会通过 parseDimens() 方法,重新计算一下输入的尺寸。

4.从这里可以看出,它支持两个尺寸,px 和 dp ,如果如果不指定尺寸,则默认认为是 px 。

到这里就完成了一次通过 wm size 命令,修改设备屏幕参数的全过程

操作注意事项:

1.手机连接电脑并打开UBS调试;

2.运行自己的app;

3.打开电脑命令行进行上述命令设置,即可看到手机不同分辨率。

常用到的手机分辨率及尺寸,仅供参考:

手机型号       density           size

一加5              420          1080x1920

红米NOTE.         320             720x1280

华为MATE7.       480             1080x1812

MOTO-G5          480             1080x1920

魅族MX3            440             1080x1800

Nexus5x             420             1080x1794

Nexus6p             560             1440x2392

奇酷360              460             1080x1920

VivoX5                320               720x1280

一部手机做好屏幕适配相关推荐

  1. android做好屏幕适配,android屏幕适配

    Android一些尺寸单位的基础概念描述 屏幕尺寸:单位英寸,屏幕对角线的物理尺寸. dp:官方是根据320480为基准指定dp值,即dpi160下,1dp=1px,在dpi320下即分辨率72010 ...

  2. 【原】android【手机】屏幕适配解决方案,完美适配适配hdpi,xhdpi,xxhdpi的做法。

    [原]android[手机]屏幕适配解决方案,完美适配适配hdpi,xhdpi,xxhdpi的做法. 参考文章: (1)[原]android[手机]屏幕适配解决方案,完美适配适配hdpi,xhdpi, ...

  3. Unity开发游戏中全面屏手机的屏幕适配

    很多人可能把全面屏跟曲面屏混淆,其实这是两个不同的概念. 一般手机的屏幕纵横比为16:9,如1080x1920.1440x2560等,其比值为1.777777--,全面屏手机出现之前,Android中 ...

  4. Unity中全面屏手机的屏幕适配问题

    unity打包apk 安装到手机上,在曲面屏手机上 上下会留有黑边,总是不能全面适配手机. 一般手机的屏幕纵横比为16:9,如1080x1920.1440x2560等,其比值为1.7左右,全面屏手机出 ...

  5. 【原】android【手机】屏幕适配解决方案,完美适配适配hdpi,xhdpi,xxhdpi的做法。...

    1.先说要怎么做,后面在慢慢讲解: 2.现在来讲解为什么要放这三套: 这三套其实按内容来说就两种,为什么这两种可以适配hdpi,xhdpi,xxhdpi呢? 那么两种类型的dimens就可以了,为什么 ...

  6. android 适配2k屏幕分辨率,Android设备兼容处理(二):屏幕适配

    前言 要做好屏幕适配最重要的是了解当前市场设备分布,目前主流设备可以分为三类,4.7-5.5英寸的中屏手机,5.5-7.0的大屏手机,以及7.0英寸以上的平板.分辨率则是720P,1080P和2K. ...

  7. android ui布局适配,Android适配全面总结(一)----屏幕适配

    前言 Android适配是一个老生常谈的问题,很多程序员觉得很恶心,不愿意做适配,但是又不得不做.然后老板说,这位兄弟,做好了,今天晚饭给你加个鸡腿,然后程序员开始找各种资料,忙活起来了,最终在苦逼的 ...

  8. Android适配全面总结(一)----屏幕适配

    版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载.https://www.jianshu.com/p/7aa34434ad4d 转载请标明出处: https:// ...

  9. 小米max android auto,Android屏幕适配的前世今生(二)

    前言 上篇文章介绍了在屏幕适配上遇到的问题,采用px或者dp都会与设计稿存在一定的偏差,也详细的介绍了dp和dpi含义和作用,本篇文章着重介绍我们应该如何做好屏幕适配的工作,以及各种屏幕适配方法发展史 ...

最新文章

  1. 英特尔在移动芯片为何衰败 看完此文豁然开朗
  2. 洛谷 - P1381 - 单词背诵 - 哈希 - 尺取
  3. 协程实现爬虫的例子主要优势在于充分利用IO时间去请求其他的url
  4. hdu 2059(dp)
  5. 使用Heroku,解决gitment登录失败,报[object ProgressEvent]的错
  6. C++中默认构造函数使用时的要点
  7. 未能成功加载扩展程序_【JAVA虚拟机(JVM)精髓】09-几种不同的类加载器
  8. Direct3D播放RGB(通过Texture)
  9. 线性表之--队列操作
  10. 一位全加器Verilog的三种不同的描述
  11. VGG16和VGG19的理解
  12. linux pci转can驱动程序,PCI转LPT并口卡驱动程序
  13. 信息系统项目管理师考试经验和心得
  14. 如何做一个自动化感应垃圾桶
  15. Linux下的java运行
  16. java 动态密码错误_什么是OTP:Java一次动态密码、付款码原理
  17. Excel一键求得单元格内数值个数的操作!
  18. “Cache-主存”和“主存和辅存”的区别
  19. python 输入输出重定向_输入输出重定向_清华尹成python入门教程_少儿编程视频-51CTO学院...
  20. 怎么监控Linux流量,linux下监控流量

热门文章

  1. python实现天气数据爬取实现数据可视化和天气查询gui界面设计
  2. 币信(BXIN)创始人唐仪(Tony Tong):币信(BXIN)坚持合规为主
  3. 微信小程序开发笔记 支付篇④——基于微信支付SDK实现Java后端接口使用
  4. 微分matlab程序,数值微分及其matlab程序.doc
  5. 电脑螺旋丸html,code_editor.html
  6. B站韩顺平java学习笔记(二十三)-- MYSQL基础篇 章节
  7. C语言 while语句
  8. 用腾讯轻联,打通草料二维码与其他应用的连接
  9. AI外呼机器人的作用
  10. C语言rand和srand函数的简单介绍和用法