1.前言
在系统10.0的rom定制化开发中,在对于某些第三方app的适配工作中,由于第三方的app的特定默认的 dpi等configuation等参数设置有点大,导致显得字体有点大,控件有点宽等,导致安装后显示很不协调, 所以就需要分析app加载的时候就修改相关的dpi等属性值来实现功能
2.系统framework层修改第三方app的dpi的属性功能实现的核心类
-
frameworks/base/core/java/android/content/res/Configuration.java
-
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中的相关配置中, 看下系统参数的相关配置
-
-
public int densityDpi;
-
-
/** @hide Hack to get this information from WM to app running in compat mode. */
-
public int compatScreenWidthDp;
-
/** @hide Hack to get this information from WM to app running in compat mode. */
-
public int compatScreenHeightDp;
-
/** @hide Hack to get this information from WM to app running in compat mode. */
-
public int compatSmallestScreenWidthDp;
-
-
public Configuration() {
-
unset();
-
}
-
-
public Configuration(Configuration o) {
-
setTo(o);
-
}
-
-
public void setTo(Configuration o) {
-
fontScale = o.fontScale;
-
mcc = o.mcc;
-
mnc = o.mnc;
-
locale = o.locale == null ? null : (Locale) o.locale.clone();
-
o.fixUpLocaleList();
-
mLocaleList = o.mLocaleList;
-
userSetLocale = o.userSetLocale;
-
touchscreen = o.touchscreen;
-
keyboard = o.keyboard;
-
keyboardHidden = o.keyboardHidden;
-
hardKeyboardHidden = o.hardKeyboardHidden;
-
navigation = o.navigation;
-
navigationHidden = o.navigationHidden;
-
orientation = o.orientation;
-
screenLayout = o.screenLayout;
-
colorMode = o.colorMode;
-
uiMode = o.uiMode;
-
screenWidthDp = o.screenWidthDp;
-
screenHeightDp = o.screenHeightDp;
-
smallestScreenWidthDp = o.smallestScreenWidthDp;
-
densityDpi = o.densityDpi;
-
compatScreenWidthDp = o.compatScreenWidthDp;
-
compatScreenHeightDp = o.compatScreenHeightDp;
-
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
-
assetsSeq = o.assetsSeq;
-
seq = o.seq;
-
windowConfiguration.setTo(o.windowConfiguration);
-
}
在实现系统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的属性值
-
/**
-
* Called when the activity is starting. This is where most initialization
-
* should go: calling {@link #setContentView(int)} to inflate the
-
* activity's UI, using {@link #findViewById} to programmatically interact
-
* with widgets in the UI, calling
-
* {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
-
* cursors for data being displayed, etc.
-
*
-
* <p>You can call {@link #finish} from within this function, in
-
* which case onDestroy() will be immediately called after {@link #onCreate} without any of the
-
* rest of the activity lifecycle ({@link #onStart}, {@link #onResume}, {@link #onPause}, etc)
-
* executing.
-
*
-
* <p><em>Derived classes must call through to the super class's
-
* implementation of this method. If they do not, an exception will be
-
* thrown.</em></p>
-
*
-
* @param savedInstanceState If the activity is being re-initialized after
-
* previously being shut down then this Bundle contains the data it most
-
* recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b>
-
*
-
* @see #onStart
-
* @see #onSaveInstanceState
-
* @see #onRestoreInstanceState
-
* @see #onPostCreate
-
*/
-
@MainThread
-
@CallSuper
-
protected void onCreate(@Nullable Bundle savedInstanceState) {
-
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
-
-
if (mLastNonConfigurationInstances != null) {
-
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
-
}
-
if (mActivityInfo.parentActivityName != null) {
-
if (mActionBar == null) {
-
mEnableDefaultActionBarUp = true;
-
} else {
-
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
-
}
-
}
-
if (savedInstanceState != null) {
-
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
-
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
-
View.LAST_APP_AUTOFILL_ID);
-
-
if (mAutoFillResetNeeded) {
-
getAutofillManager().onCreate(savedInstanceState);
-
}
-
-
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
-
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
-
? mLastNonConfigurationInstances.fragments : null);
-
}
-
mFragments.dispatchCreate();
-
dispatchActivityCreated(savedInstanceState);
-
if (mVoiceInteractor != null) {
-
mVoiceInteractor.attachActivity(this);
-
}
-
mRestoredFromBundle = savedInstanceState != null;
-
mCalled = true;
-
-
//add core start
-
ActivityManager acitivitymg = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-
List<ActivityManager.RunningTaskInfo> runningTasks = acitivitymg.getRunningTasks(1);
-
-
if (runningTasks != null && !runningTasks.isEmpty()) {
-
ComponentName topActivity = runningTasks.get(0).topActivity;
-
String packageName = topActivity.getPackageName();
-
if ("com.pne.funcation".equals(packageName)) {
-
Resources resources = getResources();
-
if (resources != null) {
-
Configuration configuration = resources.getConfiguration();
-
-
if (configuration != null) {
-
DisplayMetrics displayMetrics = new DisplayMetrics();
-
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
-
int densityDpi = displayMetrics.densityDpi;
-
// change dpi
-
if (densityDpi != 160) {
-
configuration.densityDpi = 160;
-
resources.updateConfiguration(configuration,
-
resources.getDisplayMetrics());
-
}
-
}
-
}
-
}
-
}
-
//add core end
-
}
在实现系统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的功能,就这样实现了相关的功能