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