mirror of
https://github.com/TrianguloY/LightningLauncher.git
synced 2024-12-26 09:58:20 +01:00
optimize icon pack loading with laziness
This commit is contained in:
parent
87d16ab200
commit
57a5da4901
1 changed files with 217 additions and 123 deletions
|
@ -13,17 +13,14 @@ import android.graphics.drawable.Drawable;
|
|||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.*;
|
||||
|
||||
public class IconPack {
|
||||
|
||||
|
@ -82,6 +79,214 @@ public class IconPack {
|
|||
page.reload();
|
||||
}
|
||||
|
||||
private static class LegacyIconPackResIdFetcher {
|
||||
private final Resources resources;
|
||||
private final String packageName;
|
||||
private List<String> iconNames;
|
||||
private final Map<ComponentName, Integer> cache = new HashMap<>();
|
||||
|
||||
private LegacyIconPackResIdFetcher(Resources resources, String packageName) {
|
||||
this.resources = resources;
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
private List<String> getIconNames() {
|
||||
if (iconNames == null) {
|
||||
int iconPackResId = resources.getIdentifier("icon_pack", "array", packageName);
|
||||
if (iconPackResId != 0) {
|
||||
iconNames = Arrays.asList(resources.getStringArray(iconPackResId));
|
||||
} else {
|
||||
iconNames = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
return iconNames;
|
||||
}
|
||||
|
||||
public Integer tryFindDrawableIdForComponent(ComponentName cn) {
|
||||
if (cache.containsKey(cn)) {
|
||||
return cache.get(cn);
|
||||
}
|
||||
// try to find an id, either with or without the activity name (try with the activity name first, otherwise try only the package)
|
||||
String className = cn.getClassName();
|
||||
String iconName = className.replace('.', '_').toLowerCase();
|
||||
Integer drawableId = getDrawableIdForName(iconName);
|
||||
if (drawableId == null) {
|
||||
int pos = className.lastIndexOf('.') + 1; // if not found will produce 0 which is fine
|
||||
iconName = (cn.getPackageName() + "_" + className.substring(pos)).replace('.', '_').toLowerCase();
|
||||
drawableId = getDrawableIdForName(iconName);
|
||||
if (drawableId == null) {
|
||||
iconName = cn.getPackageName().replace('.', '_').toLowerCase();
|
||||
drawableId = getDrawableIdForName(iconName);
|
||||
}
|
||||
}
|
||||
if (drawableId != null) {
|
||||
cache.put(cn, drawableId);
|
||||
}
|
||||
return drawableId;
|
||||
}
|
||||
|
||||
private Integer getDrawableIdForName(String iconName) {
|
||||
if (getIconNames().contains(iconName)) {
|
||||
try {
|
||||
return resources.getIdentifier(iconName, "drawable", packageName);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
// pass, error in input array
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static class AppFilterIconPackResIdFetcher {
|
||||
private final Map<String, String> items = new TreeMap<>();
|
||||
private final List<String> iconBacks = new ArrayList<>();
|
||||
private final Resources resources;
|
||||
private final String packageName;
|
||||
private String iconUpon = null;
|
||||
private String iconMask = null;
|
||||
private float scale = 1;
|
||||
private List<Bitmap> iconBackCache;
|
||||
private Bitmap iconUponCache;
|
||||
private Bitmap iconMaskCache;
|
||||
private final Map<ComponentName, Integer> itemCache = new TreeMap<>();
|
||||
|
||||
public AppFilterIconPackResIdFetcher(Context iconPack, String packageName) {
|
||||
this.resources = iconPack.getResources();
|
||||
this.packageName = packageName;
|
||||
InputStream appfilterStream = null;
|
||||
try {
|
||||
XmlPullParser parser;
|
||||
int appfilter_id = resources.getIdentifier("appfilter", "xml", packageName);
|
||||
if(appfilter_id != 0) {
|
||||
parser = resources.getXml(appfilter_id);
|
||||
} else {
|
||||
try {
|
||||
appfilterStream = iconPack.getAssets().open("appfilter.xml");
|
||||
parser = Xml.newPullParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||
parser.setInput(appfilterStream, null);
|
||||
} catch(IOException e) {
|
||||
parser = null;
|
||||
}
|
||||
}
|
||||
if(parser != null) {
|
||||
int eventType = parser.next();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String name = parser.getName();
|
||||
switch (name) {
|
||||
case "iconback": {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if (n == null) {
|
||||
for (int i = 1; i < 30; i++) {
|
||||
n = parser.getAttributeValue(null, "img" + i);
|
||||
if (n == null) {
|
||||
break;
|
||||
}
|
||||
iconBacks.add(n);
|
||||
}
|
||||
} else {
|
||||
iconBacks.add(n);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "iconupon": {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if (n == null) {
|
||||
n = parser.getAttributeValue(null, "img1");
|
||||
}
|
||||
iconUpon = n;
|
||||
break;
|
||||
}
|
||||
case "iconmask": {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if (n == null) {
|
||||
n = parser.getAttributeValue(null, "img1");
|
||||
}
|
||||
iconMask = n;
|
||||
break;
|
||||
}
|
||||
case "scale":
|
||||
scale = Float.parseFloat(parser.getAttributeValue(null, "factor"));
|
||||
break;
|
||||
case "item":
|
||||
String component = parser.getAttributeValue(null, "component");
|
||||
String drawable = parser.getAttributeValue(null, "drawable");
|
||||
try {
|
||||
int start = component.indexOf('{') + 1;
|
||||
String componentName = component.substring(start, component.lastIndexOf('}'));
|
||||
if (componentName.indexOf('/', start) == -1) {
|
||||
componentName = componentName.substring(0, componentName.lastIndexOf('.') - 1) + "/" + componentName;
|
||||
}
|
||||
items.put(componentName, drawable);
|
||||
} catch (Exception e) {
|
||||
Log.i("LL", "unable to decode " + component);
|
||||
// pass, error in input array
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
} finally {
|
||||
if(appfilterStream != null) try { appfilterStream.close(); } catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Bitmap> getIconBacks() {
|
||||
if(iconBackCache == null) {
|
||||
iconBackCache = new ArrayList<>();
|
||||
for (String iconBack : iconBacks) {
|
||||
Bitmap b = loadBitmapFromDrawable(resources, packageName, iconBack);
|
||||
if(b != null) {
|
||||
iconBackCache.add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
return iconBackCache;
|
||||
}
|
||||
|
||||
public Bitmap getIconUpon() {
|
||||
if(iconUponCache == null && iconUpon != null) {
|
||||
iconUponCache = loadBitmapFromDrawable(resources, packageName, iconUpon);
|
||||
}
|
||||
return iconUponCache;
|
||||
}
|
||||
|
||||
public Bitmap getIconMask() {
|
||||
if(iconMaskCache == null && iconMask != null) {
|
||||
iconMaskCache = loadBitmapFromDrawable(resources, packageName, iconMask);
|
||||
}
|
||||
return iconMaskCache;
|
||||
}
|
||||
|
||||
public float getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public Integer tryFindDrawableIdForComponent(ComponentName cn) {
|
||||
if(itemCache.containsKey(cn)) {
|
||||
return itemCache.get(cn);
|
||||
}
|
||||
Integer drawableId = null;
|
||||
String flatten = cn.flattenToString();
|
||||
if(items.containsKey(flatten)) {
|
||||
drawableId = resources.getIdentifier(items.get(flatten), "drawable", packageName);
|
||||
}
|
||||
if(drawableId != null) {
|
||||
itemCache.put(cn, drawableId);
|
||||
}
|
||||
return drawableId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
private static boolean doApplyIconPackInBackground(final Context context, final String package_name, final Page page, final int item_id) {
|
||||
Context icon_pack;
|
||||
|
@ -92,110 +297,8 @@ public class IconPack {
|
|||
}
|
||||
|
||||
Resources res = icon_pack.getResources();
|
||||
int icon_pack_res_id = res.getIdentifier("icon_pack", "array", package_name);
|
||||
|
||||
// build the cache of icon name -> drawable id (legacy way)
|
||||
HashMap<String, Integer> icon_name_ids = new HashMap<String, Integer>();
|
||||
if(icon_pack_res_id != 0) {
|
||||
String[] icon_names = res.getStringArray(icon_pack_res_id);
|
||||
for(String icon_name : icon_names) {
|
||||
try {
|
||||
int drawable_res_id = res.getIdentifier(icon_name, "drawable", package_name);
|
||||
if(drawable_res_id != 0) icon_name_ids.put(icon_name, Integer.valueOf(drawable_res_id));
|
||||
} catch(Resources.NotFoundException e) {
|
||||
// pass, error in input array
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build the cache of componentname -> drawable id and load icon layers if available
|
||||
HashMap<String, Integer> component_name_ids = new HashMap<String, Integer>();
|
||||
ArrayList<Bitmap> icon_effect_back = new ArrayList<Bitmap>();
|
||||
Bitmap icon_effect_over=null, icon_effect_mask=null;
|
||||
float icon_effect_scale = 1;
|
||||
InputStream appfilter_is = null;
|
||||
try {
|
||||
XmlPullParser parser;
|
||||
int appfilter_id = icon_pack.getResources().getIdentifier("appfilter", "xml", package_name);
|
||||
if(appfilter_id != 0) {
|
||||
parser = icon_pack.getResources().getXml(appfilter_id);
|
||||
} else {
|
||||
try {
|
||||
appfilter_is = icon_pack.getAssets().open("appfilter.xml");
|
||||
parser = Xml.newPullParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||
parser.setInput(appfilter_is, null);
|
||||
} catch(IOException e) {
|
||||
parser = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(parser == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int eventType = parser.next();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String name = parser.getName();
|
||||
if (name.equals("iconback")) {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if(n == null) {
|
||||
for(int i=1; i<30; i++) {
|
||||
n = parser.getAttributeValue(null, "img"+i);
|
||||
if(n == null) {
|
||||
break;
|
||||
}
|
||||
Bitmap b = loadBitmapFromDrawable(res, package_name, n);
|
||||
if(b != null) {
|
||||
icon_effect_back.add(b);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Bitmap b = loadBitmapFromDrawable(res, package_name, n);
|
||||
if(b != null) {
|
||||
icon_effect_back.add(b);
|
||||
}
|
||||
}
|
||||
} else if (name.equals("iconupon")) {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if(n == null) {
|
||||
n = parser.getAttributeValue(null, "img1");
|
||||
}
|
||||
icon_effect_over = loadBitmapFromDrawable(res, package_name, n);
|
||||
} else if (name.equals("iconmask")) {
|
||||
String n = parser.getAttributeValue(null, "img");
|
||||
if(n == null) {
|
||||
n = parser.getAttributeValue(null, "img1");
|
||||
}
|
||||
icon_effect_mask = loadBitmapFromDrawable(res, package_name, n);
|
||||
} else if (name.equals("scale")) {
|
||||
icon_effect_scale = Float.parseFloat(parser.getAttributeValue(null, "factor"));
|
||||
} else if (name.equals("item")) {
|
||||
String component = parser.getAttributeValue(null, "component");
|
||||
String drawable = parser.getAttributeValue(null, "drawable");
|
||||
try {
|
||||
String component_name = component.substring(component.indexOf('{')+1, component.indexOf('}'));
|
||||
if(component_name.indexOf('/') == -1) {
|
||||
component_name = component_name.substring(0, component_name.lastIndexOf('.')-1) + "/" + component_name;
|
||||
}
|
||||
ComponentName cn = ComponentName.unflattenFromString(component_name);
|
||||
|
||||
int drawable_res_id = res.getIdentifier(drawable, "drawable", package_name);
|
||||
if(drawable_res_id != 0) component_name_ids.put(cn.flattenToString(), Integer.valueOf(drawable_res_id));
|
||||
} catch(Exception e) {
|
||||
Log.i("LL", "unable to decode " + component);
|
||||
// pass, error in input array
|
||||
}
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
} finally {
|
||||
if(appfilter_is != null) try { appfilter_is.close(); } catch (IOException e) {}
|
||||
}
|
||||
LegacyIconPackResIdFetcher legacyIconPackResIdFetcher = new LegacyIconPackResIdFetcher(res, package_name);
|
||||
AppFilterIconPackResIdFetcher appFilterIconPackResIdFetcher = new AppFilterIconPackResIdFetcher(icon_pack, package_name);
|
||||
|
||||
// File pages_dir = FileUtils.getPagesDir(Customize.this);
|
||||
// String[] pages = pages_dir.list();
|
||||
|
@ -224,6 +327,7 @@ public class IconPack {
|
|||
// } catch (Exception e) {
|
||||
// // pass
|
||||
// }
|
||||
List<Bitmap> icon_effect_back = appFilterIconPackResIdFetcher.getIconBacks();
|
||||
|
||||
File icon_dir = page.getAndCreateIconDir();
|
||||
icon_dir.mkdirs();
|
||||
|
@ -231,8 +335,10 @@ public class IconPack {
|
|||
File icon_effect_back_file = new File(icon_dir, "b");
|
||||
if (icon_effect_back.size() > 0) saveBitmapToFile(icon_effect_back.get(0), icon_effect_back_file); else icon_effect_back_file.delete();
|
||||
File icon_effect_over_file = new File(icon_dir, "o");
|
||||
Bitmap icon_effect_over = appFilterIconPackResIdFetcher.getIconUpon();
|
||||
if (icon_effect_over != null) saveBitmapToFile(icon_effect_over, icon_effect_over_file); else icon_effect_over_file.delete();
|
||||
File icon_effect_mask_file = new File(icon_dir, "m");
|
||||
Bitmap icon_effect_mask = appFilterIconPackResIdFetcher.getIconMask();
|
||||
if (icon_effect_mask != null) saveBitmapToFile(icon_effect_mask, icon_effect_mask_file); else icon_effect_mask_file.delete();
|
||||
|
||||
page.setModified();
|
||||
|
@ -251,21 +357,9 @@ public class IconPack {
|
|||
ComponentName cn = s.getIntent().getComponent();
|
||||
if(cn != null) {
|
||||
// try to get an id through the appfilter way
|
||||
Integer drawable_id = component_name_ids.get(cn.flattenToString());
|
||||
Integer drawable_id = appFilterIconPackResIdFetcher.tryFindDrawableIdForComponent(cn);
|
||||
if(drawable_id == null) {
|
||||
// try to find an id, either with or without the activity name (try with the activty name first, otherwise try only the package)
|
||||
String class_name = cn.getClassName();
|
||||
String icon_name = class_name.replace('.', '_').toLowerCase();
|
||||
drawable_id = icon_name_ids.get(icon_name);
|
||||
if(drawable_id == null) {
|
||||
int pos = class_name.lastIndexOf('.')+1; // if not found will produce 0 which is fine
|
||||
icon_name = (cn.getPackageName()+"_"+class_name.substring(pos)).replace('.', '_').toLowerCase();
|
||||
drawable_id = icon_name_ids.get(icon_name);
|
||||
if(drawable_id == null) {
|
||||
icon_name = cn.getPackageName().replace('.', '_').toLowerCase();
|
||||
drawable_id = icon_name_ids.get(icon_name);
|
||||
}
|
||||
}
|
||||
drawable_id = legacyIconPackResIdFetcher.tryFindDrawableIdForComponent(cn);
|
||||
}
|
||||
|
||||
if(drawable_id != null) {
|
||||
|
@ -304,7 +398,7 @@ public class IconPack {
|
|||
} else if(icon_effect_back.size() > 1) {
|
||||
Bitmap bitmap = icon_effect_back.get((n++)%icon_effect_back.size());
|
||||
saveBitmapToFile(bitmap, ShortcutConfig.getIconBackFile(icon_dir, s.getId()));
|
||||
s.modifyShortcutConfig().iconEffectScale = icon_effect_scale;
|
||||
s.modifyShortcutConfig().iconEffectScale = appFilterIconPackResIdFetcher.getScale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue