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.os.AsyncTask;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
|
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class IconPack {
|
public class IconPack {
|
||||||
|
|
||||||
|
@ -82,6 +79,214 @@ public class IconPack {
|
||||||
page.reload();
|
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")
|
@SuppressLint("DefaultLocale")
|
||||||
private static boolean doApplyIconPackInBackground(final Context context, final String package_name, final Page page, final int item_id) {
|
private static boolean doApplyIconPackInBackground(final Context context, final String package_name, final Page page, final int item_id) {
|
||||||
Context icon_pack;
|
Context icon_pack;
|
||||||
|
@ -92,110 +297,8 @@ public class IconPack {
|
||||||
}
|
}
|
||||||
|
|
||||||
Resources res = icon_pack.getResources();
|
Resources res = icon_pack.getResources();
|
||||||
int icon_pack_res_id = res.getIdentifier("icon_pack", "array", package_name);
|
LegacyIconPackResIdFetcher legacyIconPackResIdFetcher = new LegacyIconPackResIdFetcher(res, package_name);
|
||||||
|
AppFilterIconPackResIdFetcher appFilterIconPackResIdFetcher = new AppFilterIconPackResIdFetcher(icon_pack, 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) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// File pages_dir = FileUtils.getPagesDir(Customize.this);
|
// File pages_dir = FileUtils.getPagesDir(Customize.this);
|
||||||
// String[] pages = pages_dir.list();
|
// String[] pages = pages_dir.list();
|
||||||
|
@ -224,6 +327,7 @@ public class IconPack {
|
||||||
// } catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
// // pass
|
// // pass
|
||||||
// }
|
// }
|
||||||
|
List<Bitmap> icon_effect_back = appFilterIconPackResIdFetcher.getIconBacks();
|
||||||
|
|
||||||
File icon_dir = page.getAndCreateIconDir();
|
File icon_dir = page.getAndCreateIconDir();
|
||||||
icon_dir.mkdirs();
|
icon_dir.mkdirs();
|
||||||
|
@ -231,8 +335,10 @@ public class IconPack {
|
||||||
File icon_effect_back_file = new File(icon_dir, "b");
|
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();
|
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");
|
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();
|
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");
|
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();
|
if (icon_effect_mask != null) saveBitmapToFile(icon_effect_mask, icon_effect_mask_file); else icon_effect_mask_file.delete();
|
||||||
|
|
||||||
page.setModified();
|
page.setModified();
|
||||||
|
@ -251,21 +357,9 @@ public class IconPack {
|
||||||
ComponentName cn = s.getIntent().getComponent();
|
ComponentName cn = s.getIntent().getComponent();
|
||||||
if(cn != null) {
|
if(cn != null) {
|
||||||
// try to get an id through the appfilter way
|
// 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) {
|
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)
|
drawable_id = legacyIconPackResIdFetcher.tryFindDrawableIdForComponent(cn);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(drawable_id != null) {
|
if(drawable_id != null) {
|
||||||
|
@ -304,7 +398,7 @@ public class IconPack {
|
||||||
} else if(icon_effect_back.size() > 1) {
|
} else if(icon_effect_back.size() > 1) {
|
||||||
Bitmap bitmap = icon_effect_back.get((n++)%icon_effect_back.size());
|
Bitmap bitmap = icon_effect_back.get((n++)%icon_effect_back.size());
|
||||||
saveBitmapToFile(bitmap, ShortcutConfig.getIconBackFile(icon_dir, s.getId()));
|
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