当我在 android 中滚动时,Listview 挂起
Listview hangs when I scroll in android
我正在创建音乐播放器应用程序,我使用光标从本地存储中获取歌曲。我成功地显示了歌曲和专辑封面,但是当我滚动列表时它挂起了。我应该怎么做才能解决这个问题。
这是我的光标:
cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,MediaStore.Audio.AudioColumns.DURATION+">0", null, sortOrder);
这里是 class,它将歌曲和专辑封面与列表视图字段绑定在一起:
private class MediaCursorAdapter extends SimpleCursorAdapter {
String backgroundColor = "white";
String someOtherBackgroundColor = "#F5F5F5";
public MediaCursorAdapter(Context context, int layout, Cursor c) {
super(context, layout, c,
new String[]{MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.TITLE, MediaStore.Audio.AudioColumns.DURATION,MediaStore.Audio.Media.ALBUM_ID},
new int[]{R.id.displayname, R.id.title, R.id.duration,R.id.iv_art});
}
public Bitmap getAlbumart(Context context, Long album_id){
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
try{
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null){
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
pfd = null;
fd = null;
}
} catch(Error ee){}
catch (Exception e) {}
return bm;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
if(cursor.getPosition() % 2 == 0)
{
view.setBackgroundColor(
Color.parseColor(backgroundColor));
}
else
{
view.setBackgroundColor(
Color.parseColor(someOtherBackgroundColor));
}
TextView title = (TextView) view.findViewById(R.id.title);
TextView name = (TextView) view.findViewById(R.id.displayname);
TextView duration = (TextView) view.findViewById(R.id.duration);
ImageView iv_art = (ImageView) view.findViewById(R.id.iv_art);
String a = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Long l = Long.parseLong(a);
Bitmap art = getAlbumart(songlist.this,l);
if(art!=null)
{
iv_art.setImageBitmap(art);
}
else
{
iv_art.setImageResource(R.mipmap.app_splash_screen_icon);
}
long durationInMs = Long.parseLong(cursor.getString(
cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));
name.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)));
title.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.TITLE)));
Utility d = new Utility();
String durationInMin = d.convertDuration(durationInMs);
duration.setText("" + durationInMin);
view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.listitem, parent, false);
bindView(v, context, cursor);
return v;
}
}
这是设置列表视图适配器的代码:
mediaAdapter = new MediaCursorAdapter(this, R.layout.listitem, cursor);
lv_songlist.setAdapter(mediaAdapter);
每次在 ListView
中创建新行时,都会从 UI-Thread 上的存储中加载图像。由于从存储中加载数据(尤其是图像)是一项可能需要一段时间的操作,因此 UI-Thread 会暂时阻止 UI-Thread 执行除加载该图像之外的任何工作。这会导致您遇到 "hanging"。
最佳解决方案是将图像加载卸载到不同的线程上。您可以手动执行此操作,也可以使用其中一种广泛使用的图像加载库(Picasso、Glide、UniversalImageLoader)来完成这项工作。
我正在创建音乐播放器应用程序,我使用光标从本地存储中获取歌曲。我成功地显示了歌曲和专辑封面,但是当我滚动列表时它挂起了。我应该怎么做才能解决这个问题。
这是我的光标:
cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,MediaStore.Audio.AudioColumns.DURATION+">0", null, sortOrder);
这里是 class,它将歌曲和专辑封面与列表视图字段绑定在一起:
private class MediaCursorAdapter extends SimpleCursorAdapter {
String backgroundColor = "white";
String someOtherBackgroundColor = "#F5F5F5";
public MediaCursorAdapter(Context context, int layout, Cursor c) {
super(context, layout, c,
new String[]{MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.TITLE, MediaStore.Audio.AudioColumns.DURATION,MediaStore.Audio.Media.ALBUM_ID},
new int[]{R.id.displayname, R.id.title, R.id.duration,R.id.iv_art});
}
public Bitmap getAlbumart(Context context, Long album_id){
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
try{
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null){
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
pfd = null;
fd = null;
}
} catch(Error ee){}
catch (Exception e) {}
return bm;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
if(cursor.getPosition() % 2 == 0)
{
view.setBackgroundColor(
Color.parseColor(backgroundColor));
}
else
{
view.setBackgroundColor(
Color.parseColor(someOtherBackgroundColor));
}
TextView title = (TextView) view.findViewById(R.id.title);
TextView name = (TextView) view.findViewById(R.id.displayname);
TextView duration = (TextView) view.findViewById(R.id.duration);
ImageView iv_art = (ImageView) view.findViewById(R.id.iv_art);
String a = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Long l = Long.parseLong(a);
Bitmap art = getAlbumart(songlist.this,l);
if(art!=null)
{
iv_art.setImageBitmap(art);
}
else
{
iv_art.setImageResource(R.mipmap.app_splash_screen_icon);
}
long durationInMs = Long.parseLong(cursor.getString(
cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));
name.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)));
title.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.TITLE)));
Utility d = new Utility();
String durationInMin = d.convertDuration(durationInMs);
duration.setText("" + durationInMin);
view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.listitem, parent, false);
bindView(v, context, cursor);
return v;
}
}
这是设置列表视图适配器的代码:
mediaAdapter = new MediaCursorAdapter(this, R.layout.listitem, cursor);
lv_songlist.setAdapter(mediaAdapter);
每次在 ListView
中创建新行时,都会从 UI-Thread 上的存储中加载图像。由于从存储中加载数据(尤其是图像)是一项可能需要一段时间的操作,因此 UI-Thread 会暂时阻止 UI-Thread 执行除加载该图像之外的任何工作。这会导致您遇到 "hanging"。
最佳解决方案是将图像加载卸载到不同的线程上。您可以手动执行此操作,也可以使用其中一种广泛使用的图像加载库(Picasso、Glide、UniversalImageLoader)来完成这项工作。