Solve the bug that the targetSdkVersion of the Android application is less than 24 (Android N) running on a high-version device and cannot be full-screen

foreword

When developing the company's car equipment, due to the special screen ratio (1920x720), some applications have large black borders on the left and bottom when displayed. Use dumpsys to analyze the View with black borders. After removal, it is found that it still exists . Confirm later It took a few hours to record this problem for the default ratio problem of the low version.

Conditions where the problem occurs:

  1. Android app: targetSdkVersion < 24 (Android N);
  2. The resolution aspect ratio of the device is greater than 1.86 ( 1.86 is the maximum aspect ratio of Android lower versions);
  3. The android:resizeableActivity ="true" attribute is not set in the AndroidManifest.xml of the Android application ;

problem solution

Problems have different solutions depending on the situation

  1. If you have the application source code, you can directly set the targetSdkVersion to be greater than or equal to 24 ;
  2. If you have the application source code but cannot modify the targetSdkVersion version, then set the android:resizeableActivity
    ="true" attribute in the application's AndroidManifest.xml ;
  3. If you have the application source code, but cannot modify the targetSdkVersion version, but compileSdkVersion=26 ,
    you can try to set the android:maxAspectRatio="" =" aspect ratio" attribute in the AndroidManifest.xml ;
  4. If there is no application source code, you need to try to modify the system layer to achieve the adaptation effect. For specific modifications, see the following code:

System level modification

/frameworks/base/core/java/android/content/pm/PackageParser.java
PackageParser has the following code when parsing the AndroidManifest.xml file of the APK :

public class PackageParser {
    ....
    private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
    ....
    private boolean parseBaseApplication(Package owner, Resources res,
            XmlResourceParser parser, int flags, String[] outError)
            throws XmlPullParserException, IOException {
        final ApplicationInfo ai = owner.applicationInfo;
        final String pkgName = owner.applicationInfo.packageName;
        
        TypedArray sa = res.obtainAttributes(parser,
                com.android.internal.R.styleable.AndroidManifestApplication);
        ....
        
        // 这里会去判断xml内是否有设置android:resizeableActivity属性
        if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) {
            if (sa.getBoolean(R.styleable.AndroidManifestApplication_resizeableActivity, true)) {
                // 设置该标志位后,应用的Activity可调整大小
                ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
            } else {
                // 设置该标志位后,应用的Activity不可调整大小
                ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
            }
        } else if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
            // 若应用未设置android:resizeableActivity属性,且其targetSdkVersion >= Android N (24)
            // 设置该标志位后,应用的Activity可调整大小
            ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
-       }
+        }else {
+            ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
+        }
      
    }
    
}

According to the above code, we can see that the android:resizeableActivity attribute is not set by default , and the application with targetSdkVersion < 24 will not set its Activity to be resizable, so we need to add the corresponding configuration for this situation, that is, add the above corresponding content in the code. After modification, compile it into the device, and you can see that the application is displayed in full screen.

problem analysis

In addition to the problem of not being able to full screen due to the lack of Activity resizable flags analyzed above , there is another problem about the default maximum aspect ratio ( DEFAULT_PRE_O_MAX_ASPECT_RATIO ). By modifying this value, the full screen of the application can also be achieved, but sometimes the screen ratio When the change is large, the value may have to be changed frequently, which is a bit troublesome. The following is mainly to analyze how this value works from the source code.
/frameworks/base/core/java/android/content/pm/PackageParser.java

public class PackageParser {
    ....
    private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
    ....    
    private void setMaxAspectRatio(Package owner) {
        // 对于 O 之前的应用程序默认为 (1.86) 16.7:9 纵横比,对于 O 及更高版本则未设置。
        float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O
                ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;

        if (owner.applicationInfo.maxAspectRatio != 0) {
            // 如果应用设置了android:maxAspectRatio 属性值,则使用应用程序所配置的最大宽高比。
            maxAspectRatio = owner.applicationInfo.maxAspectRatio;
        } else if (owner.mAppMetaData != null
                && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) {
            // 未设置则设置为默认的1.86
            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;
            }

            // 这里可以获取activity设置的maxAspectRatio属性,若应用和activity都设置了,则以activity的优先
            final float activityAspectRatio = activity.metaData != null
                    ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio)
                    : maxAspectRatio;
            // 将最大宽高比设置给activity
            activity.setMaxAspectRatio(activityAspectRatio);
        }
    }
}

The above is the reason why the application cannot be displayed in full screen, and the reason why another modification can also take effect.


 

Guess you like

Origin blog.csdn.net/yzwfeng/article/details/130148427