IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 10 应用显示宽高比maxAspectRatio导致应用区域显示不全的问题 -> 正文阅读

[移动开发]Android 10 应用显示宽高比maxAspectRatio导致应用区域显示不全的问题

现象:
在这里插入图片描述
代码路径:
android/frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
android/frameworks/base/core/java/android/content/pm/PackageParser.java
日志分析流程:
adb shell dumpsys activity> D:\window.txt
adb shell dumpsys window > D:\window.txt
通过dumpsys 命令看输出的overrideconfiguration中bound的值,从日志分析看,从mAppBounds数组中可以知道该应用距离左边486,并且maxAspectRatio的值为1.86

mStartActivity:
      packageName=com.spotify.music processName=com.spotify.music
      launchedFromUid=10109 launchedFromPackage=com.spotify.music userId=0
      app=ProcessRecord{d8ed953 5223:com.spotify.music/u0a109}
      Intent { act=com.spotify.mobile.android.service.action.session.LOGIN flg=0x10000000 cmp=com.spotify.music/com.spotify.mobile.android.service.LoginActivity (has extras) }
      frontOfTask=true task=TaskRecord{98078b #7 A=com.spotify.music U=0 StackId=3 sz=1}
      taskAffinity=com.spotify.music
      mActivityComponent=com.spotify.music/com.spotify.mobile.android.service.LoginActivity
      baseDir=/data/app/com.spotify.music-HT6cXhHmdVjBWex3Fa446A==/base.apk
      dataDir=/data/user/0/com.spotify.music
      stateNotNeeded=false componentSpecified=true mActivityType=standard
      compat={160dpi} labelRes=0x7f10006f icon=0x7f0802c7 theme=0x7f1101eb
      mLastReportedConfigurations:
       mGlobalConfig={1.0 ?mcc?mnc [zh_CN] ldltr sw-47dp w1433dp h440dp 160dpi nrml long land finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1920, 440) mAppBounds=Rect(486, 0 - 1919, 440) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.6}
       mOverrideConfig={1.0 ?mcc?mnc [zh_CN] ldltr sw-47dp w818dp h439dp 160dpi nrml long land finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1304, 440) mAppBounds=Rect(486, 0 - 1304, 440) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} s.3}
      CurrentConfiguration={1.0 ?mcc?mnc [zh_CN] ldltr sw-47dp w818dp h439dp 160dpi nrml long land finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1304, 440) mAppBounds=Rect(486, 0 - 1304, 440) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} s.3}
      RequestedOverrideConfiguration={0.0 ?mcc?mnc ?localeList ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?ldr ?wideColorGamut ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/? winConfig={ mBounds=Rect(0, 0 - 1304, 440) mAppBounds=null mWindowingMode=undefined mDisplayWindowingMode=undefined mActivityType=undefined mAlwaysOnTop=undefined mRotation=undefined}}
      ResolvedOverrideConfiguration={0.0 ?mcc?mnc ?localeList ?layoutDir ?swdp w818dp h439dp ?density nrml long ?ldr ?wideColorGamut land ?uimode ?night ?touch ?keyb/?/? ?nav/? winConfig={ mBounds=Rect(0, 0 - 1304, 440) mAppBounds=Rect(486, 0 - 1304, 440) mWindowingMode=undefined mDisplayWindowingMode=undefined mActivityType=undefined mAlwaysOnTop=undefined mRotation=undefined} s.3}
      bounds=Rect(0, 0 - 1304, 440)
      taskDescription: label="null" icon=null iconResource=0 iconFilename=null primaryColor=ff121212
       backgroundColor=ff121212
       statusBarColor=ff121212
       navigationBarColor=ff000000
      launchFailed=false launchCount=1 lastLaunchTime=-5m25s469ms
      haveState=false icicle=null
      state=RESUMED stopped=false delayedResume=false finishing=false
      keysPaused=false inHistory=true visible=true sleeping=false idle=true mStartingWindowState=STARTING_WINDOW_SHOWN
      fullscreen=true noDisplay=false immersive=false launchMode=2
      frozenBeforeDestroy=false forceNewConfig=false
      mActivityType=standard
       nowVisible=true lastVisibleTime=-5m25s106ms
      resizeMode=RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY
      mLastReportedMultiWindowMode=false mLastReportedPictureInPictureMode=false
      maxAspectRatio=1.86
      minAspectRatio=1.333

原因:Android P应用显示宽高比maxAspectRatio使用导致的,那么为什么maxAspectRatio=1.86会导致部分应用半屏呢?
在PackageParser.java文件中setMaxAspectRatio()方法中,如果应用的targetSdkVersion 小于26,那么maxAspectRatio 的值就是1.86,这样会导致应用半屏,还有如果targetSdkVersion 的值大于26,那么maxAspectRatio 的值就是0,这样应用就会是全屏。我们可以去看源码

/**
 * Sets every the max aspect ratio of every child activity that doesn't already have an aspect
 * ratio set.
 */
private void setMaxAspectRatio(Package owner) {
    // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater.
    // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD.
    float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O
            ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;

    if (owner.applicationInfo.maxAspectRatio != 0) {
        // Use the application max aspect ration as default if set.
        maxAspectRatio = owner.applicationInfo.maxAspectRatio;
    } else if (owner.mAppMetaData != null
            && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) {
        maxAspectRatio = owner.mAppMetaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio);
    }

    for (Activity activity : owner.activities) {
        // If the max aspect ratio for the activity has already been set, skip.
        if (activity.hasMaxAspectRatio()) {
            continue;
        }

        // By default we prefer to use a values defined on the activity directly than values
        // defined on the application. We do not check the styled attributes on the activity
        // as it would have already been set when we processed the activity. We wait to process
        // the meta data here since this method is called at the end of processing the
        // application and all meta data is guaranteed.
        final float activityAspectRatio = activity.metaData != null
                ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio)
                : maxAspectRatio;

        activity.setMaxAspectRatio(activityAspectRatio);
    }
}

解决思路:当我们进入一个Activity时候,会去先解析AndroidManifest.xml一些属性的值,我们会重新启动Activity设置宽度和高度,从Activity的启动流程分析,就找到了ActivityRecord.java中computeBound函数,在该函数中我们把maxAspectRatio 值修改为0就解决该问题

private void computeBounds(Rect outBounds) {
        outBounds.setEmpty();
        final float maxAspectRatio = 0;//info.maxAspectRatio;
        final ActivityStack stack = getStack();
        if (task == null || stack == null || task.inMultiWindowMode() || maxAspectRatio == 0
                || isInVrUiMode(getConfiguration())) {
            // We don't set override configuration if that activity task isn't fullscreen. I.e. the
            // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
            // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
            // if we are in VR mode.
            return;
        }

        // We must base this on the parent configuration, because we set our override
        // configuration's appBounds based on the result of this method. If we used our own
        // configuration, it would be influenced by past invocations.
        final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
        final int containingAppWidth = appBounds.width();
        final int containingAppHeight = appBounds.height();
        int maxActivityWidth = containingAppWidth;
        int maxActivityHeight = containingAppHeight;

        if (containingAppWidth < containingAppHeight) {
            // Width is the shorter side, so we use that to figure-out what the max. height
            // should be given the aspect ratio.
            maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
        } else {
            // Height is the shorter side, so we use that to figure-out what the max. width
            // should be given the aspect ratio.
            maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
        }

        if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
            // The display matches or is less than the activity aspect ratio, so nothing else to do.
            // Return the existing bounds. If this method is running for the first time,
            // {@link #getOverrideBounds()} will be empty (representing no override). If the method has run
            // before, then effect of {@link #getOverrideBounds()} will already have been applied to the
            // value returned from {@link getConfiguration}. Refer to
            // {@link TaskRecord#computeOverrideConfiguration}.
            outBounds.set(getOverrideBounds());
            return;
        }

        // Compute configuration based on max supported width and height.
        // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
        // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
        // bounds would end up too small.
        outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);

        if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) {
            // Position the activity frame on the opposite side of the nav bar.
            outBounds.left = appBounds.right - maxActivityWidth;
            outBounds.right = appBounds.right;
        }
    }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:32:51  更:2022-04-01 23:33:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 19:35:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码