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。

相关推荐
m0_748235954 小时前
CentOS 7使用RPM安装MySQL
android·mysql·centos
ac-er88887 小时前
Yii框架中的队列:如何实现异步操作
android·开发语言·php
流氓也是种气质 _Cookie9 小时前
uniapp 在线更新应用
android·uniapp
zhangphil11 小时前
Android ValueAnimator ImageView animate() rotation,Kotlin
android·kotlin
徊忆羽菲12 小时前
CentOS7使用源码安装PHP8教程整理
android
编程、小哥哥13 小时前
python操作mysql
android·python
Couvrir洪荒猛兽13 小时前
Android实训十 数据存储和访问
android
五味香16 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
十二测试录16 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Couvrir洪荒猛兽18 小时前
Android实训九 数据存储和访问
android