3

我目前正在开发一个 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.

几次,用户界面感觉它会以 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。

4

0 回答 0