work profile关闭时桌面图标变灰
应用变为不可用,图标变灰色,和刚毕业第一家公司当时还是Android4.4版本,Launcher做的图标变色功能有点像:用豌豆荚把安装的应用移动到sd卡,拔掉sd卡,图标变灰色,插入sd卡,应用重新变成彩色。 翻了一下之前的blog,才发现关于插卡sd卡的launcher没有写。好尴尬啊。。。
简单来写一下work profile的Launcher流程吧
操作步骤
1、work profile是Google mada测试的一项,安装Test DPC 之后,Launcher的all apps列表会有一个worp profile的栏目,里面有几个默认的apk带角标。 2、Google的launcher3默认实现了workprofile图标信息的展示 3、拖动图标到桌面,关闭work profile,图标变灰色。
图标更新逻辑
1、app/src/com/tblenovo/launcher/LauncherModel.java中收到work profile关闭的广播
public void onReceive(Context context, Intent intent) {
if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent);
final String action = intent.getAction();
if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
forceReload();
} else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)
|| Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
UserManagerCompat.getInstance(context).enableAndResetCache();
forceReload();
} else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
if (user != null) {
if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
enqueueModelUpdateTask(new PackageUpdatedTask(
PackageUpdatedTask.OP_USER_AVAILABILITY_CHANGE, user));
}
if (Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
enqueueModelUpdateTask(new UserLockStateChangedTask(user));
}
}
}else if (Intent.ACTION_WALLPAPER_CHANGED.equals(action)) {
WallpaperBgCompat.getInstance(context.getApplicationContext()).getCompressWallpaper(true);
} else if (BaseFlags.IS_DOGFOOD_BUILD && ACTION_FORCE_ROLOAD.equals(action)) {
Launcher l = (Launcher) getCallback();
l.reload();
}
}
2、app/src/com/android/launcher/model/PackageUpdatedTask.java中,OP_USER_AVAILABILITY_CHANGE操作,然后更新图标数据。 workprofile像是基于多用户去做的一个功能,默认主用户user 0,workprofile的user 我当时打断点的时候是user 10 3、省略中间的逻辑部分 4、bindUpdatedWorkspaceItems(updatedWorkspaceItems);更新图标 5、app/src/com/android/launcher/Workspace.java的updateShortcuts更新图标
void updateShortcuts(ArrayList<WorkspaceItemInfo> shortcuts) {
...
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v) {
if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView &&
updates.contains(info)) {
WorkspaceItemInfo si = (WorkspaceItemInfo) info;
BubbleTextView shortcut = (BubbleTextView) v;
Drawable oldIcon = shortcut.getIcon();
boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
&& ((PreloadIconDrawable) oldIcon).hasNotCompleted();
shortcut.applyFromWorkspaceItem(si, si.isPromise() != oldPromiseState);
}
return false;
}
});
...
}
6、app/src/com/android/launcher/BubbleTextView.java
public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean promiseStateChanged) {
applyIconAndLabel(info);
setTag(info);
if (promiseStateChanged || (info.hasPromiseIconUi())) {
applyPromiseState(promiseStateChanged);
}
applyDotState(info, false );
}
private void applyIconAndLabel(ItemInfoWithIcon info) {
FastBitmapDrawable iconDrawable = DrawableFactory.INSTANCE.get(getContext())
.newIcon(getContext(), info);
mDotParams.color = IconPalette.getMutedColor(info.iconColor, 0.54f);
setIcon(iconDrawable);
setText(info.title);
if (info.contentDescription != null) {
setContentDescription(info.isDisabled()
? getContext().getString(R.string.disabled_app_label, info.contentDescription)
: info.contentDescription);
}
}
7、app/src/com/android/launcher/graphics/DrawableFactory.java
public FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) {
FastBitmapDrawable drawable = info.usingLowResIcon()
? new PlaceHolderIconDrawable(info, IconShape.getShapePath(), context)
: new FastBitmapDrawable(info);
drawable.setIsDisabled(info.isDisabled());
return drawable;
}
尾注
简单写一点图标颜色的部分逻辑分析,没有完整的打开,launcher更新、关闭、图标变化、主菜单更新等等。 有点费时间写。
授之以渔
灵感: 我是怎么找到这个逻辑的 因为之前做过launcher,所以对桌面图标印象还是比较深的,直接找到BubbleTextView.java这个类 它其实是一个textview,设置了文字和图标在文字的那个方向
protected void applyCompoundDrawables(Drawable icon) {
mDisableRelayout = mIcon != null;
icon.setBounds(0, 0, mIconSize, mIconSize);
if (mLayoutHorizontal) {
setCompoundDrawablesRelative(icon, null, null, null);
} else {
setCompoundDrawables(null, icon, null, null);
}
mDisableRelayout = false;
}
直接在这里打断点就可以了,所以桌面图标更新都会走到这里,被调用的有点多,慢慢过滤了一下就找到了上面的流程。。。。
|