最近遇到在Launcher中对于指定的app需使用使用指定的图标,实现类似于主题的功能。要实现这样的功能就要弄清楚Launcher是如何加载app图标的。首先定位到com.android.launcher3.IconCache.java这个类的cacheLocked()方法
private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,            HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {        CacheKey cacheKey = new CacheKey(componentName, user);        CacheEntry entry = mCache.get(cacheKey);        if (entry == null) {            entry = new CacheEntry();        .......                entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);                //用于初始化应用图标                entry.icon = Utilities.createIconBitmap(                        info.getBadgedIcon(mIconDpi), mContext);            } else {        ......        return entry;    }

首先通过通过info.getBadgedIcon(mIconDpi)来获取应用原始launcher图标的Drawable,mIconDpi为图图片资源id,然后通过Utilities.createIconBitmap(Drawable icon, Context context)方法来对图标进行简单的处理(要修改所有Launcher图标的背景等,可以在此方法中修改)。

其中info.getBadgedIcon(mIconDpi)就是决定应用图标的方法。该方法最终会进入com.android.launcher3.compat.LauncherActivityInfoCompatV16.java类的getBadgedIcon()–>getIcon();通过Resources来获取图标的。
我采用的方法,首先自定义一个类,LauncherIconTheme.java,该类的内容如下

package com.android.launcher3;import com.android.launcher3.R;import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.Log;public final  class LauncherIconTheme {    //google邮箱    private static int GMAIL = R.drawable.ic_launcher_gmail;    //google地图    private static int GOOGLE_MAPS = R.drawable.ic_launcher_googlemaps;    //自定义的应用资源id    ...................    private static String TAG = "LauncherIconTheme";        //根据包名、类名获取Bitmap    public static Bitmap  getIconBitmap(Context context , String packageName , String className) {        Resources resources = context.getResources();        int iconId = getIconId(packageName, className);        if (iconId != -1){            return BitmapFactory.decodeResource(resources, iconId);        }        return null;    }        //根据包名、类名获取Drawable   要用到的就是这个方法    public static Drawable getIconDrawable(Context context , String packageName , String className) {        Resources resources = context.getResources();        int iconId = getIconId(packageName, className);        if ( iconId != -1) {            return resources.getDrawable(iconId);        }        return null;    }        //根据包名、类名获取资源定义的图标资源id    private static int getIconId(String packageName , String className){        if ( "com.google.android.gm".equals(packageName)                && "com.google.android.gm.ConversationListActivityGmail".equals(className)) {            return GMAIL;        }else if ("com.google.android.apps.maps".equals(packageName)                && "com.google.android.maps.MapsActivity".equals(className)) {            return GOOGLE_MAPS;        }else if ....................            .................................        }else{            return -1;                  }    }   }

然后在IconCache的cacheLocked方法中

    /**     * Retrieves the entry from the cache. If the entry is not present, it creates a new entry.     * This method is not thread safe, it must be called from a synchronized method.     */    private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,            HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {        CacheKey cacheKey = new CacheKey(componentName, user);        CacheEntry entry = mCache.get(cacheKey);        if (entry == null) {           .................................                entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);                //实现修改图标的逻辑                Drawable themeDrawable = LauncherIconTheme                        .getIconDrawable(mContext,                                componentName.getPackageName(), componentName.getClassName());                if ( themeDrawable != null ) {                    entry.icon = Utilities.createIconBitmap(                            themeDrawable, mContext);                }else{                    entry.icon = Utilities.createIconBitmap(                            info.getBadgedIcon(mIconDpi), mContext);                                    }            } else {             ...........................................        return entry;    }

结束
此方法中只是简单的在Launcher中实现自定义应用图标的功能,有啥不足希望大家指出,共同进步。

更多相关文章

  1. 服务--Service
  2. 关于Android(安卓)studio打包发布,以及Android签名的获取
  3. Android使用JSONObject和GSON方法解析JSON格式数据
  4. Android学习笔记_32_通过WebView实现JS代码与Java代码互相通信
  5. 第85章、系统服务之ClipBoard_Service(从零开始学Android)
  6. 单选按钮与复选框
  7. INSTALL_FAILED_CONFLICTING_PROVIDER错误解决方法
  8. Android类参考---Fragment(八)
  9. android xml解析 - sax

随机推荐

  1. android seekbar的用法
  2. ViewPager使用样例
  3. android生成缩略图
  4. android TextView 部分文字变色 工具类
  5. Android基础知识学习——界面转换
  6. android耳机广播接收
  7. android 大图片拖拽并缩放实现原理
  8. Android(安卓)IntentService 深入分析
  9. Android(安卓)中的 BACK 和 HOME 按钮的
  10. JNI基本数据类型转换