android - How to load image (icons) of apps faster in gridView? -
android - How to load image (icons) of apps faster in gridView? -
i displaying apps installed in gridview. when loading lot of apps, lets 30 or more, icons display @ default android icon , several seconds later update right icon. wondering improvements can create code create icon images display faster.
load next with: new loadiconstask().execute(mapps.toarray(new appsinstalled[]{}));
here do.
private class loadiconstask extends asynctask<appsinstalled, void, void>{ @override protected void doinbackground(appsinstalled... params) { // todo auto-generated method stub map<string, drawable> icons = new hashmap<string, drawable>(); packagemanager manager = getapplicationcontext().getpackagemanager(); // match bundle name icon, set adapter loaded map (appsinstalled app : params) { string pkgname = app.getappuniqueid(); drawable ico = null; seek { intent = manager.getlaunchintentforpackage(pkgname); if (i != null) { ico = manager.getactivityicon(i); } } grab (namenotfoundexception e) { log.e(tag, "unable find icon match based on package: " + pkgname + " : " + e.getmessage()); } icons.put(app.getappuniqueid(), ico); } madapter.seticons(icons); homecoming null; }
also populate listing of apps before loadiconstask() with
private list<app> loadinstalledapps(boolean includesysapps) { list<app> apps = new arraylist<app>(); // bundle manager contains info installed apps packagemanager packagemanager = getpackagemanager(); list<packageinfo> packs = packagemanager.getinstalledpackages(0); // packagemanager.get_meta_data (int = 0; < packs.size(); i++) { packageinfo p = packs.get(i); applicationinfo = p.applicationinfo; // skip scheme apps if shall not included if ((!includesysapps) && ((a.flags & applicationinfo.flag_system) == 1)) { continue; } app app = new app(); app.settitle(p.applicationinfo.loadlabel(packagemanager).tostring()); app.setpackagename(p.packagename); app.setversionname(p.versionname); app.setversioncode(p.versioncode); charsequence description = p.applicationinfo .loaddescription(packagemanager); app.setdescription(description != null ? description.tostring() : ""); apps.add(app); } homecoming apps; }
in regards adapter class standard. getview() looks following:
@override public view getview(int position, view convertview, viewgroup parent) { appviewholder holder; if (convertview == null) { convertview = minflater.inflate(r.layout.row, null); // creates viewholder , stores reference children view // want bind info holder = new appviewholder(); holder.mtitle = (textview) convertview.findviewbyid(r.id.apptitle); holder.micon = (imageview) convertview.findviewbyid(r.id.appicon); convertview.settag(holder); } else { // reuse/overwrite view passed assuming castable! holder = (appviewholder) convertview.gettag(); } app app = mapps.get(position); holder.settitle(app.gettitle()); if (micons == null || micons.get(app.getpackagename()) == null) { holder.seticon(mstdimg); } else { holder.seticon(micons.get(app.getpackagename())); } homecoming convertview; }
is there improve way? can somehow store images of icons in info construction , when homecoming activity can skip loadiconstask? possible? give thanks in advance.
it's surprising scheme takes much time in getting these lists, may want add together logs timestamping see 1 demanding operation.
i don't know if procedure can farther optimized, haven't used these scheme api's much, can cache list
create in onresume / oncreate
static list, , (for sake of correctness) destroy in onpause / onstop
if want consider case user may install application while in app (onpause called), can skip step.
you may want permanently cache list in sdcard , find simple , fast heuristic decide if list has changed in order recreate it. maybe number of installed packages else (to discard case when user uninstalls 3 apps , install 3 different apps, number of packages same , have observe somehow).
edit- recommend caching mechanism, should identify 1 slow operation. guessing, , question "the icons take seconds appear" looks slow operation is:
ico = manager.getactivityicon(i);
but might wrong. let's suppose i'm right, inexpensive caching can be:
1) move map<string, drawable> icons = new hashmap<string, drawable>();
outside of doinbackground root of class , create static, like:
private static map<string, drawable> sicons = new hashmap<string, drawable>()
2) in loadiconstask consider case have icon:
(appsinstalled app : params) { string pkgname = app.getappuniqueid(); if (sicons.containskey(pkgname) continue; . . . }
this because sicons
static
, live long application alive.
3) classy thing, may want alter sicons drawable
bitmap
. why? because drawable
may maintain within references views
, context
, it's potential memory leak. can bitmap
drawable
easily, calling drawable.getbitmap()
, (assuming drawable
bitmapdrawable
, because it's app icon), suming you'll have:
// static icon dictionary stores bitmaps static map<string, bitmap> sicons = new hashmap<string, bitmap>(); . . // store bitmap instead of drawable sicons.put(app.getappuniqueid(), ((bitmapdrawable)ico).getbitmap()); . . // when setting icon, create drawable holder.seticon(new bitmapdrawable(micons.get(app.getpackagename())));
this way static hashmap never leak memory.
4) may want check if it's worth store bitmaps on disk. mind additional work , it might not worth if time load icon disk similar time load icon calling ico = manager.getactivityicon(i);
. may (i don't know if manager.getactivityicon() extracts icon apk) but may not.
if check out it's worth, when create list, can save bitmaps sdcard this:
// prepare file application cache dir. file cachedfile=new file(context.getcachedir(), "icon-"+app.getpackagename()); // save our bitmap compressed jpeg bundle name filename mybitmap.compress(compressformat.jpeg, quality, new fileoutputstream(cachedfile);
... when loading icons, check if icon exists , load sdcard instead:
string key=app.getpackagename(); file localfile=new file(context.getcachedir(), "icon-"+key); if (localfile.exists()) { // file exists in sdcard, load bitmap mybitmap = bitmapfactory.decodestream(new fileinputstream(localfile)); // have our bitmap sdcard !! let's set our hashmap sicons.put(key, mybitmap) } else { // utilize slow method }
well see it's matter of identifying slow operation. if our above assumption correct, stored bitmaps survive application destroy , optimize icon loading.
android gridview
Comments
Post a Comment