Android 10.0 系统framework层修改第三方app的dpi的属性功能实现

时间:2024-09-30 07:08:28

1.前言

在系统10.0的rom定制化开发中,在对于某些第三方app的适配工作中,由于第三方的app的特定默认的 dpi等configuation等参数设置有点大,导致显得字体有点大,控件有点宽等,导致安装后显示很不协调, 所以就需要分析app加载的时候就修改相关的dpi等属性值来实现功能

2.系统framework层修改第三方app的dpi的属性功能实现的核心类

  1. frameworks/base/core/java/android/content/res/Configuration.java
  2. frameworks\base\core\java\android\app\Activity.java

3.系统framework层修改第三方app的dpi的属性功能实现的核心功能分析和实现

Configuration指的是Configuration.java这个类所代表的配置信息 它主要就是表示系统的配置信息等,比如屏幕方向, 触摸屏的触摸方式等 Configuration有哪些属性 Manifest指:在Manifest文件中,activity标签的configChanges是否可以使用 Java指:android.content.res.Configuration类中是否存在对应的属性 Configuration和Resouce的关系 从Resouce获取资源时,默认使用当前Configuration相匹配的资源。但也可以在运行时,更新Resouce关联的Configuration。 Android 活动(Activity) 活动代表了一个具有用户界面的单一屏幕,如 Java 的窗口或者帧。Android 的活动是 ContextThemeWrapper 类的子类。 如果你曾经用 C,C++ 或者 Java 语言编程,你应该知道这些程序从 main() 函数开始。很类似的,Android 系统初始化它的程序是通过活动中的 onCreate() 回调的调用开始的。 存在有一序列的回调方法来启动一个活动,同时有一序列的方法来关闭活动

3.1 Configuration.java中相关的信息配置

在实现系统framework层修改第三方app的dpi的属性功能中,通过上述的分析得知,在 Configuration.java中相关的源码配置中得知,在Configuration.java中的相关配置中, 看下系统参数的相关配置

  1. public int densityDpi;
  2. /** @hide Hack to get this information from WM to app running in compat mode. */
  3. public int compatScreenWidthDp;
  4. /** @hide Hack to get this information from WM to app running in compat mode. */
  5. public int compatScreenHeightDp;
  6. /** @hide Hack to get this information from WM to app running in compat mode. */
  7. public int compatSmallestScreenWidthDp;
  8. public Configuration() {
  9. unset();
  10. }
  11. public Configuration(Configuration o) {
  12. setTo(o);
  13. }
  14. public void setTo(Configuration o) {
  15. fontScale = o.fontScale;
  16. mcc = o.mcc;
  17. mnc = o.mnc;
  18. locale = o.locale == null ? null : (Locale) o.locale.clone();
  19. o.fixUpLocaleList();
  20. mLocaleList = o.mLocaleList;
  21. userSetLocale = o.userSetLocale;
  22. touchscreen = o.touchscreen;
  23. keyboard = o.keyboard;
  24. keyboardHidden = o.keyboardHidden;
  25. hardKeyboardHidden = o.hardKeyboardHidden;
  26. navigation = o.navigation;
  27. navigationHidden = o.navigationHidden;
  28. orientation = o.orientation;
  29. screenLayout = o.screenLayout;
  30. colorMode = o.colorMode;
  31. uiMode = o.uiMode;
  32. screenWidthDp = o.screenWidthDp;
  33. screenHeightDp = o.screenHeightDp;
  34. smallestScreenWidthDp = o.smallestScreenWidthDp;
  35. densityDpi = o.densityDpi;
  36. compatScreenWidthDp = o.compatScreenWidthDp;
  37. compatScreenHeightDp = o.compatScreenHeightDp;
  38. compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
  39. assetsSeq = o.assetsSeq;
  40. seq = o.seq;
  41. windowConfiguration.setTo(o.windowConfiguration);
  42. }

在实现系统framework层修改第三方app的dpi的属性功能中,通过上述的分析得知,在 Configuration.java中相关的源码配置中得知,在 setTo(Configuration o)中负责对系统Configuration.java 的相关配置进行重新配置,而 densityDpi = o.densityDpi;就是对dpi进行重新设置,在系统属性 densityDpi代表对dpi的属性设置,在app中可以对这个属性进行设置针对当前app的configuration 的设置功能,接下来看下怎么样配置某个app的相关属性

3.2 Activity.java中相关页面启动功能的设置

在实现系统framework层修改第三方app的dpi的属性功能中,通过上述的分析得知,在Activity中 主要负责显示app的每个页面,在这里的每个页面都是从生命周期中生成到销毁的过程,所以说 可以在这里根据包名进入到Activity里面的时候,来设置dpi的属性值

  1. /**
  2. * Called when the activity is starting. This is where most initialization
  3. * should go: calling {@link #setContentView(int)} to inflate the
  4. * activity's UI, using {@link #findViewById} to programmatically interact
  5. * with widgets in the UI, calling
  6. * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
  7. * cursors for data being displayed, etc.
  8. *
  9. * <p>You can call {@link #finish} from within this function, in
  10. * which case onDestroy() will be immediately called after {@link #onCreate} without any of the
  11. * rest of the activity lifecycle ({@link #onStart}, {@link #onResume}, {@link #onPause}, etc)
  12. * executing.
  13. *
  14. * <p><em>Derived classes must call through to the super class's
  15. * implementation of this method. If they do not, an exception will be
  16. * thrown.</em></p>
  17. *
  18. * @param savedInstanceState If the activity is being re-initialized after
  19. * previously being shut down then this Bundle contains the data it most
  20. * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b>
  21. *
  22. * @see #onStart
  23. * @see #onSaveInstanceState
  24. * @see #onRestoreInstanceState
  25. * @see #onPostCreate
  26. */
  27. @MainThread
  28. @CallSuper
  29. protected void onCreate(@Nullable Bundle savedInstanceState) {
  30. if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
  31. if (mLastNonConfigurationInstances != null) {
  32. mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
  33. }
  34. if (mActivityInfo.parentActivityName != null) {
  35. if (mActionBar == null) {
  36. mEnableDefaultActionBarUp = true;
  37. } else {
  38. mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
  39. }
  40. }
  41. if (savedInstanceState != null) {
  42. mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
  43. mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
  44. View.LAST_APP_AUTOFILL_ID);
  45. if (mAutoFillResetNeeded) {
  46. getAutofillManager().onCreate(savedInstanceState);
  47. }
  48. Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
  49. mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
  50. ? mLastNonConfigurationInstances.fragments : null);
  51. }
  52. mFragments.dispatchCreate();
  53. dispatchActivityCreated(savedInstanceState);
  54. if (mVoiceInteractor != null) {
  55. mVoiceInteractor.attachActivity(this);
  56. }
  57. mRestoredFromBundle = savedInstanceState != null;
  58. mCalled = true;
  59. //add core start
  60. ActivityManager acitivitymg = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
  61. List<ActivityManager.RunningTaskInfo> runningTasks = acitivitymg.getRunningTasks(1);
  62. if (runningTasks != null && !runningTasks.isEmpty()) {
  63. ComponentName topActivity = runningTasks.get(0).topActivity;
  64. String packageName = topActivity.getPackageName();
  65. if ("com.pne.funcation".equals(packageName)) {
  66. Resources resources = getResources();
  67. if (resources != null) {
  68. Configuration configuration = resources.getConfiguration();
  69. if (configuration != null) {
  70. DisplayMetrics displayMetrics = new DisplayMetrics();
  71. getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
  72. int densityDpi = displayMetrics.densityDpi;
  73. // change dpi
  74. if (densityDpi != 160) {
  75. configuration.densityDpi = 160;
  76. resources.updateConfiguration(configuration,
  77. resources.getDisplayMetrics());
  78. }
  79. }
  80. }
  81. }
  82. }
  83. //add core end
  84. }

在实现系统framework层修改第三方app的dpi的属性功能中,通过上述的分析得知,在Activity的 相关源码中,在onCreate(@Nullable Bundle savedInstanceState)中负责构造每一个页面的布局属性 开始启动每一个activity页面功能,所以可以在这里通过获取正在运行的app页面,来获取当前的包名 根据if ("com.pne.funcation".equals(packageName)) 来设置 Configuration这个app的属性, 然后调用resources.updateConfiguration(configuration, resources.getDisplayMetrics()); 来设置configuration.densityDpi = 160;来修改这个app的dpi的功能,就这样实现了相关的功能