This article from http://blog.csdn.net/hellogv/, reference must indicate the source!
Recently, I am working on the Android tablet, which involves the performance problem of using the gridview with high resolution. In Android mobile phone software development, if a large number of items are used on listview or gridview, many people will think of viewholder ...... yes, viewholder is very suitable for listview or a gridview with less than four items in each row. However, for a high-resolution device (Android tablet or even Android TV), if each line contains more than four items, viewholder is still used.
For example, if there are nine items in each row and the images of each item are dynamically downloaded from the network, the optimization of the gridview view is a test.
The optimization method proposed in this article is: Create a View list (list <View>) in getview (), save the recently constructed view, and read it directly from the View list during rollback, instead of dynamic building.Using this method has two advantages:
1. Quickly read past items;
2. Directly Save the view instead of bitmap, avoiding the delay caused by imageview. setimagebitmaps.
Of course, the disadvantage is a waste of memory. Therefore, you must set an upper limit to delete the oldest item if the limit is exceeded.
Let's take a look at the performance comparison between this method and viewholder:
Compare the three groups of data that the 100 items are rolled down, for example:
The speed of "cacheadapter caching 50 items" is very close to that of viewholderadapter. Because cacheadapter has a cache, there will be 1 ~ Two quick reads of item (10 ~ 20), while viewholder's reading speed per item is average.
"Cacheadapter caches 75 items" only takes a long time to scroll down for the first time. The cached items are used for the second time, so the speed is much faster.
Compare the three groups of data to which 100 items are rolled up, for example:
"Cacheadapter caches 50 items" slightly faster than viewholderadapter, and "cacheadapter caches 75 items" is still the fastest.
Summary: The speed of "cacheadapter caching 50 items" is slightly faster than that of holderview. The fastest speed of reading the most recent items is, and the faster the cached items are. The "cacheadapter caches 75 items" occupies the least memory. This is because some images fail to be downloaded and the image of the saved item is empty. In fact, the larger the cache, the more memory the item occupies.
PS: asynchronous reading of network images is used here. The successful download takes up a large amount of memory, and the download failed takes up a small amount of memory. Therefore, the memory usage is not the absolute value of a moment, memory usage is for reference only .....
The program source code in this article can be.
Cacheadapter. Java is the custom adapter for implementing cached items. The source code is as follows:
/** <Br/> * use the list to cache previous items <br/> * @ author hellogv <br/> */<br/> public class cacheadapter extends baseadapter {</P> <p> public class item {<br/> Public String itemimageurl; <br/> Public String itemtitle; <br/> Public item (string itemimageurl, string itemtitle) {<br/> This. itemimageurl = itemimageurl; <br/> This. itemtitle = itemtitle; <br/>}</P> <p> private context mcontext; <br/> private arraylist <item> mitems = new arraylist <item> (); <br/> layoutinflater Inflater; <br/> Public cacheadapter (context c) {<br/> mcontext = C; <br/> Inflater = (layoutinflater) mcontext. getsystemservice (context. layout_inflater_service); <br/>}</P> <p> Public void additem (string itemimageurl, string itemtitle) {<br/> mitems. add (new item (itemimageurl, itemtitle); <br/>}</P> <p> Public int getcount () {<br/> return mitems. size (); <br/>}</P> <p> Public item getitem (INT position) {<br/> return mitems. get (position); <br/>}</P> <p> Public long getitemid (INT position) {<br/> return position; <br/>}</P> <p> List <integer> lstposition = new arraylist <integer> (); <br/> List <View> lstview = new arraylist <View> (); </P> <p> List <integer> lsttimes = new arraylist <integer> (); <br/> long starttime = 0; <br/> Public View getview (INT position, view convertview, viewgroup parent) {<br/> starttime = system. nanotime (); </P> <p> If (lstposition. contains (position) = false) {<br/> If (lstposition. size ()> 75) // set the number of cached items <br/>{< br/> lstposition. remove (0); // Delete the first entry <br/> lstview. remove (0); // Delete the first item <br/>}< br/> convertview = Inflater. inflate (R. layout. item, null); <br/> textview text = (textview) convertview. findviewbyid (R. id. itemtext); <br/> imageview icon = (imageview) convertview. findviewbyid (R. id. itemimage); <br/> text. settext (mitems. get (position ). itemtitle); <br/> New asyncloadimage(cmd.exe cute (new object [] {icon, mitems. get (position ). itemimageurl}); </P> <p> lstposition. add (position); // Add the latest item <br/> lstview. add (convertview); // Add the latest item <br/>} else <br/>{< br/> convertview = lstview. get (lstposition. indexof (position); <br/>}</P> <p> int endtime = (INT) (system. nanotime ()-starttime); <br/> lsttimes. add (endtime); <br/> If (lsttimes. size () = 10) <br/> {<br/> int Total = 0; <br/> for (INT I = 0; I <lsttimes. size (); I ++) <br/> total = total + lsttimes. get (I); </P> <p> log. E ("10 time spent:" + total/1000 + "μs", <br/> "memory used:" + runtime. getruntime (). totalmemory ()/1024 + "kb"); <br/> lsttimes. clear (); <br/>}</P> <p> return convertview; <br/>}</P> <p>/** <br/> * asynchronously reads network images <br/> * @ author hellogv <br/> */<br /> class asyncloadimage extends asynctask <object, object, void >{< br/> @ override <br/> protected void doinbackground (object... params) {</P> <p> try {<br/> imageview = (imageview) Params [0]; <br/> string url = (string) params [1]; <br/> Bitmap bitmap = getbitmapbyurl (URL); <br/> publishprogress (new object [] {imageview, bitmap }); <br/>} catch (malformedurlexception e) {<br/> log. E ("error", E. getmessage (); <br/> E. printstacktrace (); <br/>}catch (ioexception e) {<br/> log. E ("error", E. getmessage (); <br/> E. printstacktrace (); <br/>}< br/> return NULL; <br/>}</P> <p> protected void onprogressupdate (object... progress) {<br/> imageview = (imageview) progress [0]; <br/> imageview. setimagebitmap (Bitmap) progress [1]); <br/>}</P> <p> static public bitmap getbitmapbyurl (string urlstring) <br/> throws malformedurlexception, ioexception {<br/> URL url = new URL (urlstring); <br/> urlconnection connection = URL. openconnection (); <br/> connection. setconnecttimeout (25000); <br/> connection. setreadtimeout (90000); <br/> Bitmap bitmap = bitmapfactory. decodestream (connection. getinputstream (); <br/> return bitmap; <br/>}< br/>
Among them, if (lstposition. Size ()> 75) is the key to setting the number of cached items. Here 75 items are cached.
Viewholderadapter. Java is a custom adapter that enables viewholder to load items. The source code is as follows:
/** <Br/> * use viewholder to load item <br/> * @ author hellogv <br/> */<br/> public class viewholderadapter extends baseadapter {</P> <p> public class item {<br/> Public String itemimageurl; <br/> Public String itemtitle; </P> <p> Public item (string itemimageurl, string itemtitle) {<br/> This. itemimageurl = itemimageurl; <br/> This. itemtitle = itemtitle; <br/>}</P> <p> private context mcontext; <br/> private arraylist <item> mitems = new arraylist <item> (); <br/> layoutinflater Inflater; <br/> Public viewholderadapter (context c) {<br/> mcontext = C; <br/> Inflater = (layoutinflater) mcontext. getsystemservice (context. layout_inflater_service); <br/>}</P> <p> Public void additem (string itemimageurl, string itemtitle) {<br/> mitems. add (new item (itemimageurl, itemtitle); <br/>}</P> <p> Public int getcount () {<br/> return mitems. size (); <br/>}</P> <p> Public item getitem (INT position) {<br/> return mitems. get (position); <br/>}</P> <p> Public long getitemid (INT position) {<br/> return position; <br/>}</P> <p> static class viewholder {<br/> textview text; <br/> imageview icon; <br/>}</P> <p> List <integer> lsttimes = new arraylist <integer> (); <br/> long starttime = 0; <br/> Public View getview (INT position, view convertview, viewgroup parent) {<br/> starttime = system. nanotime (); </P> <p> viewholder holder; </P> <p> If (convertview = NULL) {<br/> convertview = Inflater. inflate (R. layout. item, null); <br/> holder = new viewholder (); <br/> holder. TEXT = (textview) convertview. findviewbyid (R. id. itemtext); <br/> holder. icon = (imageview) convertview. findviewbyid (R. id. itemimage); <br/> convertview. settag (holder); <br/>}else {<br/> holder = (viewholder) convertview. gettag (); <br/>}< br/> holder. text. settext (mitems. get (position ). itemtitle); <br/> New asyncloadimage(cmd.exe cute (new object [] {holder. icon, mitems. get (position ). itemimageurl}); </P> <p> int endtime = (INT) (system. nanotime ()-starttime); <br/> lsttimes. add (endtime); <br/> If (lsttimes. size () = 10) <br/> {<br/> int Total = 0; <br/> for (INT I = 0; I <lsttimes. size (); I ++) <br/> total = total + lsttimes. get (I); </P> <p> log. E ("10 time spent:" + total/1000 + "μs", <br/> "memory used:" + runtime. getruntime (). totalmemory ()/1024 + "kb"); <br/> lsttimes. clear (); <br/>}</P> <p> return convertview; <br/>}</P> <p>/** <br/> * asynchronously reads network images <br/> * @ author hellogv <br/> */<br /> class asyncloadimage extends asynctask <object, object, void >{< br/> @ override <br/> protected void doinbackground (object... params) {</P> <p> try {<br/> imageview = (imageview) Params [0]; <br/> string url = (string) params [1]; <br/> Bitmap bitmap = cacheadapter. getbitmapbyurl (URL); <br/> publishprogress (new object [] {imageview, bitmap}); <br/>} catch (malformedurlexception e) {<br/> E. printstacktrace (); <br/>}catch (ioexception e) {<br/> E. printstacktrace (); <br/>}< br/> return NULL; <br/>}</P> <p> protected void onprogressupdate (object... progress) {<br/> imageview = (imageview) progress [0]; <br/> imageview. setimagebitmap (Bitmap) progress [1]); <br/>}</P> <p >}< br/>
Testperformance. Java is the main program. You can test the performance of cacheadapter and viewholderadapter by using the annotator. The source code is as follows:
Public class testperformance extends activity {<br/>/** called when the activity is first created. */<br/> @ override <br/> Public void oncreate (bundle savedinstancestate) {<br/> super. oncreate (savedinstancestate); <br/> setcontentview (R. layout. main); <br/> This. settitle ("gridview view Cache Optimization on Android tablet ----- hellogv"); <br/> gridview = (gridview) findviewbyid (R. id. gridview); <br/> cacheadapter adapter = new cacheadapter (this); <br/> // viewholderadapter adapter = new viewholderadapter (this); </P> <p> gridview. setadapter (adapter); <br/> string urlimage = ""; // select a static image on the Network </P> <p> for (INT I = 0; I <100; I ++) <br/>{< br/> adapter. additem (urlimage, "+" + I + ""); <br/>}</P> <p >}< br/>}