Note that there are some explanatory texts on larger screens.

plurals
  1. POBad Listview Performance on Nexus 4, good on Nexus 7
    text
    copied!<p>I am developing an Android application at the moment. This application has to deal with large lists alot (thousands of entries, it's actually a playlist).</p> <p>To add the possibility to reorder the entries, I use the drag-sort-listview library. Additionally, each row has a ProgressBar in it. This bar is only visible on the current item (so just one for the whole list). However, I am running into huge performance problems on my Nexus 4 (CM 10.1.2 final), while the performance is good at my Nexus 7 (2012, Stock). I tracked the CPU usage while scrolling the list as fast as I can (without using the fastscroll mechanism. On the Nexus 7, CPU usage stayed below 30%, but on the Nexus 4 it hit 80% and the list was extremely laggy. Logcat output had the line </p> <pre><code>I/Choreographer(639): Skipped xx frames! The application may be doing too much work on its main thread. </code></pre> <p>a few times and the UI felt like it would render with 1fps.</p> <p>The problem is that I can't imagine the reason for this. I am using the ViewHolder pattern in my adapter. Because of custom fonts, I am also using a font cache.</p> <p>The getView() Method of my adapter:</p> <pre><code>@Override public View getView(int position, View convertView, ViewGroup arg2) { PlaylistItem playlistItem = items.get(position); ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item_playlist, null); holder = new ViewHolder(); holder.tv_artist = (TextView) convertView.findViewById(R.id.tv_artist); holder.tv_number = (TextView) convertView.findViewById(R.id.tv_number); holder.tv_number_in_queue = (TextView) convertView.findViewById(R.id.tv_number_in_queue); holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title); holder.tv_track_length = (TextView) convertView.findViewById(R.id.tv_track_length); holder.progressBar = (ProgressBar) convertView.findViewById(R.id.progressBar1); holder.drag_point = (ImageView) convertView.findViewById(R.id.drag_point); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //Show Artist and title holder.tv_artist.setText(playlistItem.getArtist()); holder.tv_title.setText(playlistItem.getTitle()); if (queuedItems.get(position) != null) holder.tv_number_in_queue.setText("[" + (queuedItems.get(position) + 1) + "]"); else holder.tv_number_in_queue.setText(""); //Show track length if (playlistItem.getLength() &gt; -1) holder.tv_track_length.setText(playlistItem.getLengthInHours()); else holder.tv_track_length.setText(""); //Show index in playlist holder.tv_number.setText(playlistItem.getDisplayNumber()); // Show the progressbar and set progress if the item is the currently playing one if (playlistItem.getIndex() == currentItem) { holder.progressBar.setVisibility(View.VISIBLE); if (currentTrackLength &gt; 0) { if (holder.progressBar.getMax() != currentTrackLength) { holder.progressBar.setMax(currentTrackLength); } holder.progressBar.setProgress(currentTrackPos); } else { holder.progressBar.setMax(1); holder.progressBar.setProgress(1); } } else { holder.progressBar.setVisibility(View.INVISIBLE); } return convertView; } static class ViewHolder { TextView tv_number; TextView tv_title; TextView tv_artist; TextView tv_track_length; TextView tv_number_in_queue; ProgressBar progressBar; ImageView drag_point; } </code></pre> <p>The layout of a single list item:</p> <p> </p> <pre><code>&lt;RelativeLayout android:id="@+id/rl_top_container" android:layout_width="match_parent" android:layout_height="@dimen/playlist_fragment_item_height" android:background="?attr/background_playlist_item" &gt; &lt;ImageView android:id="@+id/drag_point" android:layout_width="40dp" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:paddingLeft="10dp" android:paddingRight="10dp" android:scaleType="centerInside" android:src="?attr/drag_sort_icon" /&gt; &lt;TextView android:id="@+id/tv_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/drag_point" android:text="1" android:textAppearance="?android:attr/textAppearance" android:textColor="?attr/foreground_text_color_secondary" android:textSize="@dimen/playlist_fragment_title_size" /&gt; &lt;RelativeLayout android:id="@+id/rl_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_toRightOf="@+id/tv_number" &gt; &lt;TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/tv_track_length" android:singleLine="true" android:text="Title" android:textColor="?attr/foreground_text_color" android:textSize="@dimen/playlist_fragment_title_size" /&gt; &lt;TextView android:id="@+id/tv_artist" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_title" android:layout_toLeftOf="@+id/tv_number_in_queue" android:singleLine="true" android:text="Artist" android:textColor="?attr/foreground_text_color_secondary" android:textSize="@dimen/playlist_fragment_artist_size" /&gt; &lt;TextView android:id="@+id/tv_number_in_queue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/tv_artist" android:layout_alignParentEnd="true" android:padding="3dp" android:textColor="?attr/foreground_text_color_secondary" android:textSize="@dimen/playlist_fragment_additional_info_size" /&gt; &lt;TextView android:id="@+id/tv_track_length" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentTop="false" android:layout_alignTop="@+id/tv_title" android:padding="3dp" android:textColor="?attr/foreground_text_color_secondary" android:textSize="@dimen/playlist_fragment_additional_info_size" /&gt; &lt;/RelativeLayout&gt; &lt;ProgressBar android:id="@+id/progressBar1" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="@dimen/playlist_fragment_item_margin_progress_bar" android:visibility="invisible" /&gt; &lt;/RelativeLayout&gt; </code></pre> <p></p> <p>The listview:</p> <pre><code>&lt;com.mobeta.android.dslv.DragSortListView android:id="@+id/list_playlist" dslv:drag_handle_id="@+id/drag_point" android:layout_width="match_parent" android:layout_height="match_parent" android:fastScrollEnabled="true" android:dividerHeight="0dp" android:divider="@null" dslv:drag_enabled="true" dslv:collapsed_height="2dp" dslv:drag_scroll_start="0.33" dslv:max_drag_scroll_speed="1.0" dslv:float_alpha="0.6" dslv:slide_shuffle_speed="0.3" dslv:use_default_controller="true"&gt; &lt;/com.mobeta.android.dslv.DragSortListView&gt; </code></pre> <p>I absolutely ran out of ideas. Logcat did only show 2 or 3 GC calls while scrolling by the way, so I think this won't be the reason.</p> <p>Any idea welcome! Thank you.</p> <p>EDIT: Ok now it's getting really weird. Just ran the code on a HTC Desire Z (aka G2... 800Mhz, 512MB RAM) with Android 2.3.5 and Sense... even here it's much smoother than on the Nexus 4?! What is gong on? Could CyanogenMod cause this misbehaviour? I am asking, because I don't want to flash another ROM just because of a suspicion.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload