另一天,另一个问题!我目前正在为学校的作业创建一个音乐播放器。从我制作和填充ListView的第1天开始,ListView就像疯了似的一样。几天前,我开始使用LruCache缓存我的图像,但没有注意到性能提升。今天我在ViewHolders中添加了,但同样,没有任何性能提升。
在我的ListView中,可以显示文件夹项目或歌曲项目。文件夹项目在其视图中显示相册图像(2个文本视图旁边)。现在它是从我的可绘制资源中抽取的一些硬编码图像(大小范围在15KB到55KB之间)。一首歌曲项目只有4个TextView。当列表只有歌曲项目时,滞后会少一点,但仍然太多。
目前ListView中最多有10个项目。下面是用于创建列表的ArrayAdapter。我对Android非常陌生,所以任何帮助/提示都会受到赞赏,即使它与此问题无关。
public class SongAdapter extends ArrayAdapter{
private final LruCache<String, Bitmap> cache;
private ArrayList<Integer> myFolderSongCounts;
ViewHolderSongs holderSongs;
ViewHolderFolders holderFolders;
public SongAdapter(Context context, List objects, ArrayList<Integer> folderSongCounts) {
super(context, 0, objects);
myFolderSongCounts = folderSongCounts;
/*
*
* CACHE EXAMPLE FROM
* https://stackoverflow.com/questions/15586977/listview-scroll-lagging-when-images-is-shown
* BY USER Lam Do
*
* */
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
cache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getRowBytes() / 1024;
}
};
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
File song = (File) getItem(position);
Log.d("SongAdapter Position: ", ""+ position);
Listen main = (Listen) getContext().getApplicationContext();
Typeface custom_font = main.getCustom_font();
//if its an mp3 file, show a song list item
if(song.getName().substring(song.getName().length()-4,song.getName().length()).equals(".mp3")) {
Mp3File mp3file = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(song.getPath());
try {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.songs_list_item, parent, false);
holderSongs = new ViewHolderSongs();
holderSongs.txt_song_album = (TextView) convertView.findViewById(R.id.song_album);
holderSongs.txt_song_artist = (TextView) convertView.findViewById(R.id.song_artist);
holderSongs.txt_song_duration = (TextView) convertView.findViewById(R.id.song_duration);
holderSongs.txt_song_name = (TextView) convertView.findViewById(R.id.song_name);
convertView.setTag(holderSongs);
}
else {
holderSongs = (ViewHolderSongs) convertView.getTag();
}
mp3file = new Mp3File(song);
String album = mp3file.getId3v2Tag().getAlbum();
String artist = mp3file.getId3v2Tag().getAlbumArtist();
int durationInMilliseconds = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
int durationInSeconds = durationInMilliseconds/1000;
int durationMinutes = durationInSeconds/60;
String durationSeconds = (durationInSeconds%60 > 10) ? "" + durationInSeconds%60 : "0" + durationInSeconds%60;
String duration = durationMinutes + ":" + durationSeconds;
holderSongs.txt_song_name.setText(song.getName().substring(0, song.getName().length() - 4));
holderSongs.txt_song_album.setText(getValidValue(album, "undefined"));
holderSongs.txt_song_artist.setText(getValidValue(artist, "undefined"));
holderSongs.txt_song_duration.setText(getValidValue(duration, "0:00"));
holderSongs.txt_song_name.setTypeface(custom_font);
holderSongs.txt_song_album.setTypeface(custom_font);
holderSongs.txt_song_artist.setTypeface(custom_font);
holderSongs.txt_song_duration.setTypeface(custom_font);
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedTagException e) {
e.printStackTrace();
} catch (InvalidDataException e) {
e.printStackTrace();
}
}
//if its a folder, show a folder list item
else {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.folders_list_item, parent, false);
holderFolders = new ViewHolderFolders();
holderFolders.amount_of_songs = (TextView)convertView.findViewById(R.id.amount_of_songs);
holderFolders.folder_name = (TextView)convertView.findViewById(R.id.folder_name);
holderFolders.folder_image = (ImageView)convertView.findViewById(R.id.folder_image);
convertView.setTag(holderFolders);
}
else {
holderFolders = (ViewHolderFolders) convertView.getTag();
}
int amountOfSongs = myFolderSongCounts.get(position);
holderFolders.folder_name.setText(song.getName());
holderFolders.amount_of_songs.setText(amountOfSongs + " songs");
holderFolders.folder_name.setTypeface(custom_font);
holderFolders.amount_of_songs.setTypeface(custom_font);
if(position == 0){
Bitmap bmp = getBitmapFromMemCache("perfectlychilled");
if (bmp == null) {
bmp = BitmapFactory.decodeResource(convertView.getResources(), R.drawable.perfectly_chilled);
addBitmapToMemoryCache("perfectlychilled", bmp);
}
holderFolders.folder_image.setImageBitmap(bmp);
}
else if(position == 1){
Bitmap bmp = getBitmapFromMemCache("insurgency");
if (bmp == null) {
bmp = BitmapFactory.decodeResource(convertView.getResources(), R.drawable.insurgency);
addBitmapToMemoryCache("insurgency", bmp);
}
holderFolders.folder_image.setImageBitmap(bmp);
}
else {
Bitmap bmp = getBitmapFromMemCache("default");
if (bmp == null) {
bmp = BitmapFactory.decodeResource(convertView.getResources(), R.drawable.folderdefault);
addBitmapToMemoryCache("default", bmp);
}
holderFolders.folder_image.setImageBitmap(bmp);
}
}
return convertView;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
cache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return cache.get(key);
}
static class ViewHolderSongs {
TextView txt_song_name;
TextView txt_song_album;
TextView txt_song_artist;
TextView txt_song_duration;
}
static class ViewHolderFolders {
TextView folder_name;
TextView amount_of_songs;
ImageView folder_image;
}
}
songs_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_margin="0dp"
android:padding="0dp"
android:background="@color/backgroundGray"
android:gravity="center_vertical"
android:layout_height="70dp">
<TextView
android:text="TextView"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingRight="20dp"
android:id="@+id/song_name"
android:textColor="@color/textBlack"
android:maxLines="1"
android:layout_marginBottom="8dp"
android:ellipsize="end" />
<TextView
android:text="3:26"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textAlignment="textEnd"
android:paddingRight="15dp"
android:maxLines="1"
android:ellipsize="end"
android:textColor="@color/textBlack"
android:layout_toRightOf="@id/song_name"
android:id="@+id/song_duration"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/song_artist"
android:textColor="@color/textGray"
android:width="190dp"
android:gravity="bottom"
android:maxLines="1"
android:ellipsize="end"
android:layout_below="@id/song_name"
android:paddingRight="20dp"
android:paddingLeft="15dp"
android:text="Sabaton" />
<TextView
android:text="Hell is upon us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/textGray"
android:width="190dp"
android:id="@+id/song_album"
android:paddingRight="15dp"
android:textAlignment="textEnd"
android:maxLines="1"
android:ellipsize="end"
android:layout_below="@id/song_name"
android:layout_toRightOf="@id/song_artist"
/>
</RelativeLayout>
folders_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:background="@color/backgroundGray"
android:padding="0dp"
android:layout_height="115dp">
<ImageView
android:layout_height="match_parent"
android:id="@+id/folder_image"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:padding="0dp"
android:layout_width="115dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:padding="0dp"
android:layout_marginLeft="30dp">
<TextView
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:padding="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/folder_name"
android:layout_weight="50"
android:elevation="14dp"
android:textIsSelectable="false"
android:gravity="bottom"
android:paddingBottom="5dp"
android:textAppearance="@android:style/TextAppearance.Material.Medium"
android:textColor="@color/textBlack"/>
<TextView
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:paddingTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/amount_of_songs"
android:layout_weight="50"
android:textColor="@color/textGray"/>
</LinearLayout>
</LinearLayout>
答案 0 :(得分:0)
文档https://developer.android.com/reference/android/media/MediaMetadataRetriever.html
- 的setDataSource 设置要使用的数据源(FileDescriptor)。关闭文件描述符是调用者的责任。一旦此呼叫返回,这样做是安全的。在此类的其余方法之前调用此方法。 此方法可能非常耗时。
你必须检索歌曲&#39;适配器外部的信息,并将原始信息传递到适配器。