Android Development notes -- ViewHolder and listviewviewholder for ListView loading Performance Optimization
Not long ago, when I was working on an android project, one of the functions was to crawl news from a website and use ListView to display the news. Although the pages were paginated, I still felt that it could not achieve the ideal smooth effect.
I checked some information on the Internet and found some good summaries. Here I will record them to facilitate the review.
When the ListView has a large amount of data to load, it will occupy a large amount of memory, affecting performance.
After testing, it is found that a large amount of resources are consumed when ListView loads layout files, that is, findViewById. In this case, we should consider how to reuse this layout file object, to reduce object creation.
ListView loads data in the public View getView (int position, View convertView, ViewGroup parent) {} method (when we customize the adapter, such as BaseAdapter, SimpleAdapter, cursorAdapter and other getvView methods). To optimize the loading speed of ListView, make convertView match the list type and reuse convertView to the maximum extent.
Getview can be loaded in the following ways:
The slowest loading method is to re-define a View loading layout every time and then load data.
1 public View getView(int position, View convertView, ViewGroup parent) { 2 3 View item = mInflater.inflate(R.layout.list_item_icon_text, null); 4 5 (TextView) item.findViewById(R.id.text)).setText(DATA[position]); 6 7 (ImageView) item.findViewById(R.id.icon)).setImageBitmap( 8 9 (position & 1) == 1 ? mIcon1 : mIcon2);10 11 return item;12 13 }
The correct loading method is to directly re-use convertView when convertView is not empty, which reduces unnecessary View creation and then loads data.
1 public View getView(int position, View convertView, ViewGroup parent) {2 if (convertView == null) {3 convertView = mInflater.inflate(R.layout.item, parent, false);4 }5 (TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);6 (ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(7 (position & 1) == 1 ? mIcon1 : mIcon2);8 return convertView;9 }
The fastest way is to define a ViewHolder (Object holding class), set the tag of convetView to ViewHolder, and use it again when it is not empty.
1 static class ViewHolder { 2 TextView text; 3 ImageView icon; 4 } 5 6 public View getView(int position, View convertView, ViewGroup parent) { 7 ViewHolder holder; 8 9 if (convertView == null) {10 convertView = mInflater.inflate(R.layout.list_item_icon_text,11 parent, false);12 holder = new ViewHolder();13 holder.text = (TextView) convertView.findViewById(R.id.text);14 holder.icon = (ImageView) convertView.findViewById(R.id.icon);15 convertView.setTag(holder);16 } else {17 holder = (ViewHolder) convertView.getTag();18 }19 holder.text.setText(DATA[position]);20 holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);21 return convertView;22 }
Three loading efficiency methods are shown in the following figure:
Note: The above three examples are taken from the google 2010 I/O conference.
When processing time-consuming resource loading, you need to do the following to make your loading faster and smoother:
1. Modify the adapter in the main thread of the interface
2. data can be obtained anywhere, but data should be requested in another place
3. Submit the adapter changes in the main interface thread and call the yydatasetchanged () method (update the data source)
How can I handle memory overflow when loading a large amount of text on each item in android ListView?
This design goes to listview optimization.
First, the listview must be written in the convertView and viewHolder formats strictly to ensure optimal data.
Secondly, image optimization is required if the custom Item involves images and so on. You can release bitmap without doing so.
Third, try to avoid using static in BaseAdapter to define global static variables, which has a great impact. static is a keyword in Java. When it is used to modify member variables, this variable belongs to this class, not the instance of this class. Therefore, static variables have a long life cycle. If you use them to reference instances that consume too much resources (for example, Context is the most common ), in this case, we should try to avoid using it ..
Fourth, try to avoid using threads in the ListView adapter, because the main cause of thread Memory leakage is that the thread lifecycle is uncontrollable.
Finally, if you have done the above, your listview has been optimized very well. For your problem, whether the height of your listview control is set to fill_parent, because warp will cause the listview sliding to calculate its own height infinitely. Whether your text has been loaded by threads or repeatedly. Whether the variables in your item generate new memory objects Infinitely multiple times.
Listview optimization methods (original)
Listview A view that shows items in a vertically scrolling list. A list view that displays a vertical scroll subitem. In android development, there are many places where listview is used to display data and form a vertical view. Using listview is a standard adapter mode. The data is displayed as needed by the data --, interface -- xml, and adapter -- adapter. xml describes how the data is displayed, activities. If a custom adapter is used, the getView method will be rewritten to generate the view and data for the item in the getView method. As shown in the figure: Here is an optimization, that is, reusing the view to reduce memory consumption and accelerate item loading. The Optimization in getView is very common. I have summarized the Three optimization methods below. please correct me. First, the convertView is reused, which greatly reduces the memory consumption. If you determine whether convertView is null, You need to generate a view. Then, you can return the View data to the bottom layer and present it to the user. Feature: if the current convertView is null, a view is generated through LayoutInflat. View Code 2: There is a drawback in the above writing, that is, each time you get a View, you need to re-find the findViewById, re-find the control, and then assign values to the control and set the event accordingly. In this case, we are actually doing the same thing, because the geiview actually contains these controls, and the IDs of these controls are the same, that is, as long as the findViewById is in the view, findViewById is not required each time. The second writing method is provided below. There is usually an internal class ViewHolder. This ViewHolder is used to identify some controls in the view to facilitate the setting of Event-related operations, such as onClick, so you don't have to use findViewById every time, reducing the performance consumption. At the same time, convertView is reused, which greatly reduces memory consumption. View Code 3: I personally think this writing method is the most comfortable. The most comfortable way is to look at the Code with a very nice and clear look. Feature. The internal class ViewHolder is used and convertView is reused. The second difference is that a temporary variable "View view = convertView" is used, the view is modified, and the viewView Code is returned. The preceding variable is a centralized method for beginners to learn and summarize. The source Code is as follows: LisViewTest.zip according to the suggestions provided by friends downstairs, we found there are some optimizations. The latest update is as follows: View Code @ Override public View getView (int position, View convertView, ViewGroup parent) {View view = convertView; ViewHolder holder; if (view = null) {view = LayoutInflater. from (context ). inflate (R. layout. section_list_item1, null); holder = new ViewHolder (); holder. TV _name = (TextView) view. findViewById (R. id. contact_contactinfoitem_ TV _name); holder. TV _phone = (TextView) view. findView ...... remaining full text>