网站实施过程,电子商务网站开发技术有哪些,wordpress在新窗口打开,下载室内设计排版模板网站有哪些1.前言
在12.0的系统rom定制化中#xff0c;在某些时候安装第三方应用#xff0c;突然会发现应用左右两侧为全屏有黑边显示#xff0c;所以这时候需要进行 优化#xff0c;看问题出在哪#xff0c;然后解决这个问题#xff0c;接下来分析下相关问题
2.第三方应用左右两…1.前言
在12.0的系统rom定制化中在某些时候安装第三方应用突然会发现应用左右两侧为全屏有黑边显示所以这时候需要进行 优化看问题出在哪然后解决这个问题接下来分析下相关问题
2.第三方应用左右两侧未全屏有黑边问题解决的核心类 frameworks\base\core\java\android\content\pm\parsing\component\ParsedActivityUtils.java
3.第三方应用左右两侧未全屏有黑边问题解决的核心功能分析和实现
在android7.0以后在AndroidManifest.xml中的 application 标签隐式添加一个属性android:resizeableActivity“true”, 该属性的作用后面将详细说明。 在 标签中增加属性android:resizeableActivity“false”同时在节点下增加一个meta-data标签
原理说明
在Android 7.0API 级别 24或更高版本的应用android:resizeableActivity属性默认为true对应适配方式1。这个属性是控制多窗口显示的决定当前的应用或者Activity是否支持多窗口。 可以在清单的activity或 application节点中设置该属性启用或禁用多窗口显示配置如下 android:resizeableActivity[“true” | “false”]
如果该属性设置为 trueActivity 将能以分屏和自由形状模式启动。 如果此属性设置为 falseActivity 将不支持多窗口模式。 如果该值为 false且用户尝试在多窗口模式下启动 Activity该 Activity 将全屏显示。
适配方式2即为设置屏幕的最大长宽比这是官方提供的设置方式。 如果设置了最大长宽比必须android:resizeableActivity“false”。 否则最大长宽比没有任何作用
这是android12开始支持了多窗口和分屏等功能对一些低版本sdk的应用兼容性有了调整如果不想改变targetsdk到更高也可以为Activity增加resizeableActivity属性同样可以达到去除黑边效果。 activityandroid:name.YourActivityandroid:resizeableActivitytrue/activity
以上两种解决办法适用于自己开发的应用但对应腾讯视频这种第三方应用就只能从系统层面去解决了。 接下来看下第三方应用如何处理两边黑屏的问题 ParsedActivityUtils 是Android系统中用于解析 AndroidManifest.xml 文件中的一个类主要负责解析Activity、Service、Receiver等组件的信息。 功能和作用
ParsedActivityUtils类在Android系统中主要用于解析AndroidManifest.xml文件中的Activity、Service和Receiver等组件的信息。它通过读取XML文件中的标签和属性将这些信息转换为Java对象以便系统能够正确地管理和调用这些组件。具体功能包括 解析Activity信息读取Activity的标签、名称、启动模式等信息。 解析Service信息读取Service的标签、名称、启动方式等信息。 解析Receiver信息读取Receiver的标签、名称、接收的Intent等信息。
3.1ParsingPackageUtils.java的相关解析代码分析 public class ParsingPackageUtils {public ParsingPackageUtils(boolean onlyCoreApps, String[] separateProcesses,DisplayMetrics displayMetrics, NonNull Callback callback) {mOnlyCoreApps onlyCoreApps;mSeparateProcesses separateProcesses;mDisplayMetrics displayMetrics;mCallback callback;} 在ParsingPackageUtils的构造方法中主要是构造callback参数供解析的时候回调参数使用的接下来主要看解析的最主要的方法parseBaseApplication 接下来看parseBaseApplication的具体解析方式方法 private ParseResultParsingPackage parseBaseApplication(ParseInput input,ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)throws XmlPullParserException, IOException {final String pkgName pkg.getPackageName();int targetSdk pkg.getTargetSdkVersion();TypedArray sa res.obtainAttributes(parser, R.styleable.AndroidManifestApplication);try {// TODO(b/135203078): Remove this and force unit tests to mock an empty manifest// This case can only happen in unit tests where we sometimes need to create fakes// of various package parser data structures.if (sa null) {return input.error(application does not contain any attributes);}String name sa.getNonConfigurationString(R.styleable.AndroidManifestApplication_name,0);if (name ! null) {String packageName pkg.getPackageName();String outInfoName ParsingUtils.buildClassName(packageName, name);if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) {return input.error(application invalid android:name);} else if (outInfoName null) {return input.error(Empty class name in package packageName);}pkg.setClassName(outInfoName);}....TypedValue v sa.peekValue(R.styleable.AndroidManifestApplication_fullBackupContent);int fullBackupContent 0;if (v ! null) {fullBackupContent v.resourceId;if (v.resourceId 0) {if (PackageParser.DEBUG_BACKUP) {Slog.v(TAG, fullBackupContent specified as boolean (v.data 0 ? false : true));}// false -1, true 0fullBackupContent v.data 0 ? -1 : 0;}pkg.setFullBackupContent(fullBackupContent);}if (PackageParser.DEBUG_BACKUP) {Slog.v(TAG, fullBackupContent fullBackupContent for pkgName);}}if (sa.getBoolean(R.styleable.AndroidManifestApplication_persistent, false)) {// Check if persistence is based on a feature being presentfinal String requiredFeature sa.getNonResourceString(R.styleable.AndroidManifestApplication_persistentWhenFeatureAvailable);pkg.setPersistent(requiredFeature null || mCallback.hasFeature(requiredFeature));}......String classLoaderName pkg.getClassLoaderName();if (classLoaderName ! null !ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {return input.error(Invalid class loader name: classLoaderName);}pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1));} finally {sa.recycle();}boolean hasActivityOrder false;boolean hasReceiverOrder false;boolean hasServiceOrder false;final int depth parser.getDepth();int type;while ((type parser.next()) ! XmlPullParser.END_DOCUMENT (type ! XmlPullParser.END_TAG|| parser.getDepth() depth)) {if (type ! XmlPullParser.START_TAG) {continue;}final ParseResult result;String tagName parser.getName();boolean isActivity false;switch (tagName) {case activity:isActivity true;// fall-throughcase receiver:ParseResultParsedActivity activityResult ParsedActivityUtils.parseActivityOrReceiver(mSeparateProcesses, pkg,res, parser, flags, PackageParser.sUseRoundIcon, input);if (activityResult.isSuccess()) {ParsedActivity activity activityResult.getResult();if (isActivity) {hasActivityOrder | (activity.getOrder() ! 0);pkg.addActivity(activity);} else {hasReceiverOrder | (activity.getOrder() ! 0);pkg.addReceiver(activity);}}result activityResult;break;case service:ParseResultParsedService serviceResult ParsedServiceUtils.parseService(mSeparateProcesses, pkg, res, parser,flags, PackageParser.sUseRoundIcon, input);if (serviceResult.isSuccess()) {ParsedService service serviceResult.getResult();hasServiceOrder | (service.getOrder() ! 0);pkg.addService(service);}result serviceResult;break;case provider:ParseResultParsedProvider providerResult ParsedProviderUtils.parseProvider(mSeparateProcesses, pkg, res, parser,flags, PackageParser.sUseRoundIcon, input);if (providerResult.isSuccess()) {pkg.addProvider(providerResult.getResult());}result providerResult;break;case activity-alias:activityResult ParsedActivityUtils.parseActivityAlias(pkg, res,parser, PackageParser.sUseRoundIcon, input);if (activityResult.isSuccess()) {ParsedActivity activity activityResult.getResult();hasActivityOrder | (activity.getOrder() ! 0);pkg.addActivity(activity);}result activityResult;break;default:result parseBaseAppChildTag(input, tagName, pkg, res, parser, flags);break;}if (result.isError()) {return input.error(result);}}if (TextUtils.isEmpty(pkg.getStaticSharedLibName())) {// Add a hidden app detail activity to normal apps which forwards user to App Details// page.ParseResultParsedActivity a generateAppDetailsHiddenActivity(input, pkg);if (a.isError()) {// Error should be impossible here, as the only failure case as of SDK R is a// string validation error on a constant :app_details string passed in by the// parsing code itself. For this reason, this is just a hard failure instead of// deferred.return input.error(a);}pkg.addActivity(a.getResult());}if (hasActivityOrder) {pkg.sortActivities();}if (hasReceiverOrder) {pkg.sortReceivers();}if (hasServiceOrder) {pkg.sortServices();}// Must be run after the entire {link ApplicationInfo} has been fully processed and after// every activity info has had a chance to set it from its attributes.setMaxAspectRatio(pkg);setMinAspectRatio(pkg);setSupportsSizeChanges(pkg);pkg.setHasDomainUrls(hasDomainURLs(pkg));return input.success(pkg);} 从上述代码中可以看出在parseBaseApplication中解析xml时可以对tag的值为activity,receiver,service,provider,activity-alias等几种类型的组件进行解析 在activity-alias这种tag就是对activity的别类的解析而这里也是今天实现默认启动Launcher的重点部分在解析activity的实现调用的是ParsedActivityUtils.parseActivityOrReceiver 进行解析的,最后代码还是由parseActivityOrAlias来负责解析的所以接下来看这部分代码
3.2 ParsedActivityUtils相关解析源码分析
NonNullVisibleForTesting(visibility VisibleForTesting.Visibility.PACKAGE)public static ParseResultParsedActivity parseActivityOrReceiver(String[] separateProcesses,ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags,boolean useRoundIcon, ParseInput input)throws XmlPullParserException, IOException {final String packageName pkg.getPackageName();final ParsedActivityactivity new ParsedActivity();...//int resizeMode getActivityResizeMode(pkg, sa, screenOrientation);int resizeMode ActivityInfo.RESIZE_MODE_RESIZEABLE; //固定开启resizeable属性...}
ParseResult()方法中重写resizeMode值即可。这样就可以从系统层面解决所有应用显示黑边问题包括安装的第三方应用。