最近遇到一个问题,就是在4.4.2 的Launcher3中设置非默认壁纸后,进入Setting选择辅助设置勾选大字体后回到桌面,发现壁纸被拉伸。
通过测试发现设置壁纸时Launcher已经将壁纸的长宽保存在data/data/com.android.launcher3/shared_prefs的WallpaperCropActivity.xml中
当用户通过Launcher3设置Wallpaper时会通过WallpaperCropActivity的updateWallpaperDimensions方法将当前的wallpaper的长宽保存在上述sharedpreferences里面
protected void updateWallpaperDimensions(int width, int height) {
String spKey = getSharedPreferencesKey();
SharedPreferences sp = getSharedPreferences(spKey,Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (width != 0 && height != 0) {
editor.putInt(WALLPAPER_WIDTH_KEY,width);
editor.putInt(WALLPAPER_HEIGHT_KEY,height);
} else {
editor.remove(WALLPAPER_WIDTH_KEY);
editor.remove(WALLPAPER_HEIGHT_KEY);
}
editor.commit();
suggestWallpaperDimension(getResources(),
sp, getWindowManager(),WallpaperManager.getInstance(this));
}
通过AndroidManifest.xml发现WallpaperCropActivity是运行在android:process=":wallpaper_chooser"进程中的,所以当前获取的SharedPreferences 也是在wallpaper_chooser进程中的。
当此时设置大字体后Launcher的界面被重新创建(其他情况导致界面重新加载时也会重现),在Workspace.java初始化setup时会调用
setWallpaperDimension方法:
protectedvoid setWallpaperDimension() {
String spKey = WallpaperCropActivity.getSharedPreferencesKey();
SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
WallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
sp, mLauncher.getWindowManager(),mWallpaperManager);
}
可以看到此方法中也获取了SharedPreferences,然后调用了WallpaperPickerActivity.suggestWallpaperDimension方法:
static public void suggestWallpaperDimension(Resourcesres,
finalSharedPreferences sharedPrefs,
WindowManager windowManager,
finalWallpaperManager wallpaperManager) {
final PointdefaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
new Thread("suggestWallpaperDimension"){
public voidrun() {
// Ifwe have saved a wallpaper width/height, use that instead
intsavedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
intsavedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
}
}.start();
}
此方法中会获取sharedPrefs中之前设置的壁纸大小来初始化wallpaper的大小,如果获取不到将使用默认的壁纸大小做替代,默认大小为屏高和2倍的屏宽。当前获取sharedpreferences是从Launcher进程发起的,所以此时两个进程同时操作一个sharedpreferences导致数据不能同步,Launcher进程中不能获取到wallpaper_chooser进程写入大壁纸大小,所以便使用默认壁纸大小替代,所以当前壁纸被拉伸到默认大小。
修改方法:
在获取SharedPreferences时添加Context.MODE_MULTI_PROCESS的FLAG
SharedPreferences sp = mLauncher.getSharedPreferences(spKey,Context.MODE_PRIVATE| Context.MODE_MULTI_PROCESS);
这样多进程变可以同时操作一个SharedPreferences了。
第一篇博客,排版不好大家见谅~