Android 12系统源码_多屏幕(一)多屏幕设备显示Activity

前言

  • 分屏:是指一个屏幕分出多个窗口,分别显示不同应用的界面,这在当前的手机设备中很常见。
  • 多屏:是指一个设备存在多个屏幕,这些可能是虚拟屏幕或者实体硬件屏幕,不同的应用同时显示在不同的屏幕中,或者相同应用的不同页面同时现在在不同的屏幕中。

在我们日常生活中所接触的大部分以Android系统为载体的智能化硬件设备,大多都只有一个屏幕,但是有的时候会出现需要多个屏幕的场景,特别是随着新能源汽车行业竞争的白热化,越来越多的车厂倾向于通过多屏幕来获得消费者的青睐,比如为汽车主驾副驾所对应的主屏副屏等等,这就导致车机系统的多屏幕场景越来越多;而在智能手机端,多屏协助的场景也越来越多,比如将手机屏幕内容实时投放到大屏电视上已得到更好的视觉体验;

一、模拟辅助设备

1.1、模拟辅助设备功能开关

1、在Android开发者选项里面有一个模拟辅助设备功能开关。

2、此功能默认为无,当我们点击并选择一个分辨率的时候,屏幕上会多出来一个小窗口。

这个小窗口其实就是系统新创建的一个虚拟屏幕,只不过Android系统将该虚拟屏幕的视图实时绘制在了此窗口上。

1.2、屏幕设备信息

1、我们通过adb执行dumpsys display指令,可以看到系统中当前存在的屏幕设备的相关信息。

java 复制代码
  Logical Displays: size=1
  Display 0:
    mDisplayId=0
    mPhase=1
    mLayerStack=0
    mHasContent=true
    mDesiredDisplayModeSpecs={baseModeId=1 allowGroupSwitching=false primaryRefreshRateRange=[0 60] appRequestRefreshRateRange=[0 60]}
    mRequestedColorMode=0
    mDisplayOffset=(0, 0)
    mDisplayScalingDisabled=false
    mPrimaryDisplayDevice=内置屏幕
    mBaseDisplayInfo=DisplayInfo{"内置屏幕", displayId 0", displayGroupId 0, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, real 1080 x 2400, largest app 1080 x 2400, smallest app 1080 x 2400, appVsyncOff 1000000, presDeadline 16666666, mode 1, defaultMode 1, modes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[90.0, 120.00001]}, {id=2, width=1080, height=2400, fps=120.00001, alternativeRefreshRates=[60.000004, 90.0]}, {id=3, width=1080, height=2400, fps=90.0, alternativeRefreshRates=[60.000004, 120.00001]}], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[1, 2, 3, 4], mMaxLuminance=420.0, mMaxAverageLuminance=210.1615, mMinLuminance=0.323}, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type INTERNAL, uniqueId "local:4630946545580055170", app 1080 x 2400, density 440 (419.449 x 419.257) dpi, layerStack 0, colorMode 0, supportedColorModes [0, 7, 9], address {port=130, model=0x40446d58ef1f1a}, deviceProductInfo DeviceProductInfo{name=, manufacturerPnpId=QCM, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.07496032, installOrientation ROTATION_0}
    mOverrideDisplayInfo=DisplayInfo{"内置屏幕", displayId 0", displayGroupId 0, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, real 1080 x 2400, largest app 2313 x 2269, smallest app 1080 x 949, appVsyncOff 1000000, presDeadline 16666666, mode 1, defaultMode 1, modes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[90.0, 120.00001]}, {id=2, width=1080, height=2400, fps=120.00001, alternativeRefreshRates=[60.000004, 90.0]}, {id=3, width=1080, height=2400, fps=90.0, alternativeRefreshRates=[60.000004, 120.00001]}], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[1, 2, 3, 4], mMaxLuminance=420.0, mMaxAverageLuminance=210.1615, mMinLuminance=0.323}, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type INTERNAL, uniqueId "local:4630946545580055170", app 1080 x 2269, density 440 (419.449 x 419.257) dpi, layerStack 0, colorMode 0, supportedColorModes [0, 7, 9], address {port=130, model=0x40446d58ef1f1a}, deviceProductInfo DeviceProductInfo{name=, manufacturerPnpId=QCM, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.07496032, installOrientation ROTATION_0}
    mRequestedMinimalPostProcessing=false
    mFrameRateOverrides=[]
    mPendingFrameRateOverrideUids={}

2、默认情况下系统只有一个屏幕设备信息,而在我们开启模拟辅助显示设备功能开关之后,Android系统中便会多出来一个屏幕设备信息。

java 复制代码
  Logical Displays: size=2
  Display 0:
    mDisplayId=0
    mPhase=1
    mLayerStack=0
    mHasContent=true
    mDesiredDisplayModeSpecs={baseModeId=1 allowGroupSwitching=false primaryRefreshRateRange=[0 60] appRequestRefreshRateRange=[0 60]}    mRequestedColorMode=0
    mDisplayOffset=(0, 0)
    mDisplayScalingDisabled=false
    mPrimaryDisplayDevice=内置屏幕
    mBaseDisplayInfo=DisplayInfo{"内置屏幕", displayId 0", displayGroupId 0, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, real 1080 x 2400, largest app 1080 x 2400, smallest app 1080 x 2400, appVsyncOff 1000000, presDeadline 16666666, mode 1, defaultMode 1, modes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[90.0, 120.00001]}, {id=2, width=1080, height=2400, fps=120.00001, alternativeRefreshRates=[60.000004, 90.0]}, {id=3, width=1080, height=2400, fps=90.0, alternativeRefreshRates=[60.000004, 120.00001]}], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[1, 2, 3, 4], mMaxLuminance=420.0, mMaxAverageLuminance=210.1615, mMinLuminance=0.323}, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type INTERNAL, uniqueId "local:4630946545580055170", app 1080 x 2400, density 440 (419.449 x 419.257) dpi, layerStack 0, colorMode 0, supportedColorModes [0, 7, 9], address {port=130, model=0x40446d58ef1f1a}, deviceProductInfo DeviceProductInfo{name=, manufacturerPnpId=QCM, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.07496032, installOrientation ROTATION_0}
    mOverrideDisplayInfo=DisplayInfo{"内置屏幕", displayId 0", displayGroupId 0, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, real 1080 x 2400, largest app 2313 x 2269, smallest app 1080 x 949, appVsyncOff 1000000, presDeadline 16666666, mode 1, defaultMode 1, modes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[90.0, 120.00001]}, {id=2, width=1080, height=2400, fps=120.00001, alternativeRefreshRates=[60.000004, 90.0]}, {id=3, width=1080, height=2400, fps=90.0, alternativeRefreshRates=[60.000004, 120.00001]}], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[1, 2, 3, 4], mMaxLuminance=420.0, mMaxAverageLuminance=210.1615, mMinLuminance=0.323}, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type INTERNAL, uniqueId "local:4630946545580055170", app 1080 x 2269, density 440 (419.449 x 419.257) dpi, layerStack 0, colorMode 0, supportedColorModes [0, 7, 9], address {port=130, model=0x40446d58ef1f1a}, deviceProductInfo DeviceProductInfo{name=, manufacturerPnpId=QCM, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.07496032, installOrientation ROTATION_0}
    mRequestedMinimalPostProcessing=false
    mFrameRateOverrides=[]
    mPendingFrameRateOverrideUids={}

  Display 2:
    mDisplayId=2
    mPhase=1
    mLayerStack=2
    mHasContent=false
    mDesiredDisplayModeSpecs={baseModeId=4 allowGroupSwitching=false primaryRefreshRateRange=[0 60] appRequestRefreshRateRange=[0 60]}    mRequestedColorMode=0
    mDisplayOffset=(0, 0)
    mDisplayScalingDisabled=false
    mPrimaryDisplayDevice=叠加视图 #1
    mBaseDisplayInfo=DisplayInfo{"叠加视图 #1", displayId 2", displayGroupId 0, FLAG_PRESENTATION, FLAG_TRUSTED, real 1280 x 720, largest app 1280 x 720, smallest app 1280 x 720, appVsyncOff 0, presDeadline 33333332, mode 4, defaultMode 4, modes [{id=4, width=1280, height=720, fps=60.000004, alternativeRefreshRates=[]}], hdrCapabilities null, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type OVERLAY, uniqueId "overlay:1", app 1280 x 720, density 213 (213.0 x 213.0) dpi, layerStack 2, colorMode 0, supportedColorModes [0], deviceProductInfo null, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, installOrientation ROTATION_0}
    mOverrideDisplayInfo=DisplayInfo{"叠加视图 #1", displayId 2", displayGroupId 0, FLAG_PRESENTATION, FLAG_TRUSTED, real 1280 x 720, largest app 1280 x 1280, smallest app 720 x 720, appVsyncOff 0, presDeadline 33333332, mode 4, defaultMode 4, modes [{id=4, width=1280, height=720, fps=60.000004, alternativeRefreshRates=[]}], hdrCapabilities null, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, type OVERLAY, uniqueId "overlay:1", app 1280 x 720, density 213 (213.0 x 213.0) dpi, layerStack 2, colorMode 0, supportedColorModes [0], deviceProductInfo null, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, installOrientation ROTATION_0}
    mRequestedMinimalPostProcessing=false
    mFrameRateOverrides=[]
    mPendingFrameRateOverrideUids={}

可以发现此事屏幕变成了两个。

二、将页面显示到特定屏幕中

2.1 获取当前屏幕设备信息

1、在Android系统默认情况下,我们新建一个Activity,并将其启动。

DisplayInfoActivity.java

java 复制代码
public class DisplayInfoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        TextView tvDisplayInfo = findViewById(R.id.tv_display_info);
        Display display = getDisplay();
        tvDisplayInfo.setText(display.toString());
    }
}

main_activity.xml

java 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_display_info"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:gravity="center"
        android:text="屏幕设备信息"
        android:textColor="#F00"
        android:textSize="30sp" />
        
</LinearLayout>

2、默认显示效果如下所示。

通过Activity显示的信息我们可以发现,该页面当前显示的屏幕设备id为0,名字叫做内置屏幕。

2.2 将页面显示到其他屏幕上

1、当我们为Android系统开启了模拟辅助显示设备的功能之后,此时我们通过代码打开一个新的Activity,并为其指定displayid为2,这样这个新的Activity就会显示到这个新的虚拟屏幕中。

DisplayInfoActivity.java

java 复制代码
public class DisplayInfoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        TextView tvDisplayInfo = findViewById(R.id.tv_display_info);
        Display display = getDisplay();
        tvDisplayInfo.setText(display.toString());
        findViewById(R.id.btn_open_activity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(DisplayInfoActivity.this, DisplayInfoActivity.class);
                ActivityOptions activityOptions = ActivityOptions.makeBasic();
                activityOptions.setLaunchDisplayId(2);//指定要显示到displayid为2的屏幕设备上
                startActivity(intent, activityOptions.toBundle());
            }
        });
    }

}

main_activity.xml

xml 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_display_info"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:gravity="center"
        android:text="屏幕设备信息"
        android:textColor="#F00"
        android:textSize="30sp" />

    <Button
        android:id="@+id/btn_open_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="在模拟辅助设备中显示新页面" />
</LinearLayout>

2、当我们点击按钮的时候,当前页面会从主屏幕消失,并显示到模拟辅助功能所开启的窗口里面。

通过Activity显示的信息我们可以发现,该页面当前显示的屏幕设备id为2,名字叫做叠加视图,也就是新增的虚拟屏幕设备ID。

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui