我正在开发一个Android应用程序。这个应用程序必须处理大型列表(数千个条目,它实际上是一个播放列表)。
为了添加重新排序条目的可能性,我使用了drag-sort-listview库。此外,每行中都有一个ProgressBar。此栏仅在当前项目上可见(因此整个列表只有一个)。 但是,我在Nexus 4(CM 10.1.2 final)上遇到了巨大的性能问题,而我的Nexus 7(2012,Stock)的性能却很好。我尽可能快地滚动列表来跟踪CPU使用率(不使用fastscroll机制。在Nexus 7上,CPU使用率保持在30%以下,但在Nexus 4上它达到80%且列表非常滞后.Logcat输出有行
I/Choreographer(639): Skipped xx frames! The application may be doing too much work on its main thread.
几次,UI感觉它会用1fps渲染。
问题在于我无法想象其原因。我在我的适配器中使用ViewHolder模式。由于自定义字体,我也使用字体缓存。
我的适配器的getView()方法:
@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() > -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 > 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;
}
单个列表项的布局:
<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" >
<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" />
<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" />
<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" >
<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" />
<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" />
<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" />
<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" />
</RelativeLayout>
<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" />
</RelativeLayout>
列表视图:
<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">
</com.mobeta.android.dslv.DragSortListView>
我绝对没有想法。顺便滚动时,Logcat只显示2或3个GC调用,所以我认为这不是原因。
欢迎任何想法!谢谢。
编辑:好的,现在变得非常奇怪。刚刚使用Android 2.3.5和Sense在HTC Desire Z(又名G2 ... 800Mhz,512MB RAM)上运行代码......即使在这里它比在Nexus 4上更流畅?什么是锣? CyanogenMod会导致这种不端行为吗?我问,因为我不想仅因为怀疑而闪存另一个ROM。