android multi-display

来源:互联网 发布:日线引用60分钟数据 编辑:程序博客网 时间:2024/05/22 16:48

android 系统定制之多屏幕尺寸

背景是我们的系统支持多luncher,然后希望每个luncher都有一个分辨率。这两天追了一下代码发现修改的东西主要集中在 WindowManagerService

我们知道,android提供了很便利的修改屏幕分辨率的方法

adb shell wm size 1080x1920
adb shell wm density 360
adb shell wm size reset
adb shell wm density reset

在android 应用中是这样拿屏幕尺寸的:

WindowManager wm = (WindowManager) activity        .getSystemService(Context.WINDOW_SERVICE);Point point = new Point();wm.getDefaultDisplay().getRealSize(point); StringBuilder sb = new StringBuilder();sb.append("width:").append(wm.getDefaultDisplay().getWidth()).append(",height:").append(wm.getDefaultDisplay().getHeight());sb.append("\nx:").append(point.x).append(",y:").append(point.y);WindowManager wm1 = activity.getWindowManager();sb.append("\nwidth:").append(wm1.getDefaultDisplay().getWidth()).append(",height:").append(wm1.getDefaultDisplay().getHeight());WindowManager manager = activity.getWindowManager();DisplayMetrics outMetrics = new DisplayMetrics();manager.getDefaultDisplay().getMetrics(outMetrics);sb.append("\nwidth:").append(outMetrics.widthPixels).append(",height:").append(outMetrics.heightPixels);Resources resources = activity.getResources();DisplayMetrics dm = resources.getDisplayMetrics();sb.append("\nwidth:").append(dm.widthPixels).append(",height:").append(dm.heightPixels).append(",density").append(dm.density);Rect rect = new Rect();rootView.getWindowVisibleDisplayFrame(rect);sb.append("\nwidth:").append(rect.width()).append(",height:").append(rect.height());sb.append(hasNavBar(activity) ? "\nhas" : "\nno").append(" virtual keyboard");Log.e("ScreenUtil", sb.toString());

调用栈很长,不列出来了,从wm到app,跨进程调用的是:

/frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java

@Overridepublic void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {    setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);}private void setDisplayInfoOverrideFromWindowManagerInternal(        int displayId, DisplayInfo info) {    synchronized (mSyncRoot) {        LogicalDisplay display = mLogicalDisplays.get(displayId);        if (display != null) {            if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);                scheduleTraversalLocked(false);            }        }    }}

./frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

/** Do not call if mDisplayReady == false */DisplayInfo updateDisplayAndOrientationLocked() {    ...    mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(                displayContent.getDisplayId(), displayInfo);    ...}private DisplayContent newDisplayContentLocked(final Display display) {    DisplayContent displayContent = new DisplayContent(display, this);    final int displayId = display.getDisplayId();    if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);    mDisplayContents.put(displayId, displayContent);    DisplayInfo displayInfo = displayContent.getDisplayInfo();    final Rect rect = new Rect();    mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);    synchronized (displayContent.mDisplaySizeLock) {        displayInfo.overscanLeft = rect.left;        displayInfo.overscanTop = rect.top;        displayInfo.overscanRight = rect.right;        displayInfo.overscanBottom = rect.bottom;        mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(                displayId, displayInfo);    }    configureDisplayPolicyLocked(displayContent);    // TODO: Create an input channel for each display with touch capability.    if (displayId == Display.DEFAULT_DISPLAY) {        displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);        registerPointerEventListener(displayContent.mTapDetector);    }    return displayContent;}

那么就是修改下 setDisplayInfoOverrideFromWindowManager 的方法就可以了。但是修改了之后,目测事件的分法会乱掉。

点击事件的映射,回头弄完再说吧。

查了一下api,发现android8完整的实现了这个功能

https://developer.android.com/about/versions/oreo/android-8.0.html
https://developer.android.com/guide/topics/ui/picture-in-picture.html

有一篇很不错的博客浅析Android的窗口。

看到andriod6里面好多,TODO,好麻烦,不如拉android8的代码下来比较比较,这样改得快一点

十一月九号更新


改了一轮发现完全支持的话,好多东西都会动到,现在用最轻量级的修改:

修改方法是这样的,

1,在

frameworks/base/core/java/android/view/Display.java
frameworks/base/core/java/android/view/DisplayInfo.java

在 mDisplayInfo 赋值的时候修改。

2,在

Resources.getDisplayMetrics()

那里也要抄送一下

原创粉丝点击