此文章边分析边修改,仅用作个人记录,如有不对欢迎指正!
本文的目的是要给foler添加一个icon字段:
<folder
launcher:screen="3"
launcher:x="0"
launcher:y="0"
launcher:spanX="2"
launcher:spanY="2"
launcher:title="@string/folder_name_test"
launcher:icon="@drawable/ic_allapps_pressed">
其中launcher:icon字段是无效的。
桌面的预制大家都知道是在default_workspace.xml文件中修改,那么首先就必须对这个文件进行解析:
1、LauncherProvider.java
<span style="font-size:14px;">public class LauncherProvider extends ContentProvider </span>
是从
<span style="font-size:14px;">ContentProvider </span>
继承来的,很明显是解析完xml后来保存数据的。(ContentProvider作为android的几大组件之一,后面准备花时间好好分析一下);下面是真正解析的函数:
<span style="font-size:14px;"> public int loadFavorites(SQLiteDatabase db, int workspaceResourceId) {
if(LauncherLog.DEBUG) {
LauncherLog.d(TAG, "loadFavorite begin: workspaceResourceId = " + workspaceResourceId);
}
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ContentValues values = new ContentValues();
PackageManager packageManager = mContext.getPackageManager();
int allAppsButtonRank =
mContext.getResources().getInteger(R.integer.hotseat_all_apps_index);
int i = 0;
try {
XmlResourceParser parser = mContext.getResources().getXml(workspaceResourceId);
AttributeSet attrs = Xml.asAttributeSet(parser);
beginDocument(parser, TAG_FAVORITES);
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
boolean added = false;
final String name = parser.getName();
if(LauncherLog.DEBUG) {
LauncherLog.d(TAG, "loadFavorites: name = " + name);
}
//这一堆就是xml的解析了
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);
long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
if (a.hasValue(R.styleable.Favorite_container)) {
container = Long.valueOf(a.getString(R.styleable.Favorite_container));
}
String screen = a.getString(R.styleable.Favorite_screen);
String x = a.getString(R.styleable.Favorite_x);
String y = a.getString(R.styleable.Favorite_y);
// If we are adding to the hotseat, the screen is used as the position in the
// hotseat. This screen can't be at position 0 because AllApps is in the
// zeroth position.
if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
&& Integer.valueOf(screen) == allAppsButtonRank) {
throw new RuntimeException("Invalid screen position for hotseat item");
}
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER, container);
values.put(LauncherSettings.Favorites.SCREEN, screen);
values.put(LauncherSettings.Favorites.CELLX, x);
values.put(LauncherSettings.Favorites.CELLY, y);
//这就是解析出来的赋值了</span>
<span style="font-size:14px;">//下面就是根据解析出来的名字具体的加载对应tag项,作为对每个tag的研究是很好的下手地方</span>
<span style="font-size:14px;"> if (TAG_FAVORITE.equals(name)) {
long id = addAppShortcut(db, values, a, packageManager, intent);
added = id >= 0;
} else if (TAG_SEARCH.equals(name)) {
added = addSearchWidget(db, values);
} else if (TAG_CLOCK.equals(name)) {
added = addClockWidget(db, values);
} else if (TAG_APPWIDGET.equals(name)) {
added = addAppWidget(parser, attrs, type, db, values, a, packageManager);
} else if (TAG_SHORTCUT.equals(name)) {
long id = addUriShortcut(db, values, a);
added = id >= 0;
} else if (TAG_FOLDER.equals(name)) {
String title;
int titleResId = a.getResourceId(R.styleable.Favorite_title, -1);
if (titleResId != -1) {
title = mContext.getResources().getString(titleResId);
} else {
title = mContext.getResources().getString(R.string.folder_name);
}
values.put(LauncherSettings.Favorites.TITLE, title);
long folderId = addFolder(db, values);//这一块也是对解析的字段来赋值
added = folderId >= 0;
ArrayList<Long> folderItems = new ArrayList<Long>();
int folderDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > folderDepth) {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String folder_item_name = parser.getName();
TypedArray ar = mContext.obtainStyledAttributes(attrs,
R.styleable.Favorite);
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER, folderId);
if (TAG_FAVORITE.equals(folder_item_name) && folderId >= 0) {
long id =
addAppShortcut(db, values, ar, packageManager, intent);
if (id >= 0) {
folderItems.add(id);
}
} else if (TAG_SHORTCUT.equals(folder_item_name) && folderId >= 0) {
long id = addUriShortcut(db, values, ar);
if (id >= 0) {
folderItems.add(id);
}
} else {
throw new RuntimeException("Folders can " +
"contain only shortcuts");
}
ar.recycle();
} //上面试
// We can only have folders with >= 2 items, so we need to remove the
// folder and clean up if less than 2 items were included, or some
// failed to add, and less than 2 were actually added
if (folderItems.size() < 2 && folderId >= 0) {
// We just delete the folder and any items that made it
deleteId(db, folderId);
if (folderItems.size() > 0) {
deleteId(db, folderItems.get(0));
}
added = false;
}
}
if (added) i++;
a.recycle();
}
} catch (XmlPullParserException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
} catch (IOException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
} catch (RuntimeException e) {
Log.w(TAG, "Got exception parsing favorites.", e);
}
if(LauncherLog.DEBUG) {
LauncherLog.d(TAG, "loadFavorites end: i = " + i);
}
return i;
}
</span>
先来分析favorite的:
private long addAppShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
PackageManager packageManager, Intent intent) {
long id = -1;
ActivityInfo info;
String packageName = a.getString(R.styleable.Favorite_packageName);
String className = a.getString(R.styleable.Favorite_className);
try {
ComponentName cn;
try {
cn = new ComponentName(packageName, className);
info = packageManager.getActivityInfo(cn, 0);
} catch (PackageManager.NameNotFoundException nnfe) {
String[] packages = packageManager.currentToCanonicalPackageNames(
new String[] { packageName });
cn = new ComponentName(packages[0], className);
info = packageManager.getActivityInfo(cn, 0);
}
id = generateNewId();
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
values.put(Favorites.INTENT, intent.toUri(0));
values.put(Favorites.TITLE, info.loadLabel(packageManager).toString());
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
values.put(Favorites.SPANX, 1);
values.put(Favorites.SPANY, 1);
values.put(Favorites._ID, generateNewId());
if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
return -1;
}
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Unable to add favorite: " + packageName +
"/" + className, e);
}
return id;
}