Android Listview项目在单击通知时重复

Android Listview项目在单击通知时重复,android,listview,Android,Listview,如果我在后台播放歌曲并单击通知图标返回应用程序,则会复制listView项目。首次打开应用程序时,项目不会重复。有什么不对劲吗?在我的适配器类下面发布 适配器: @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; ViewHolder holder = null; final int pos = positio

如果我在后台播放歌曲并单击通知图标返回应用程序,则会复制listView项目。首次打开应用程序时,项目不会重复。有什么不对劲吗?在我的适配器类下面发布

适配器:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;
    ViewHolder holder = null;
    final int pos = position;

    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) parent.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = (RelativeLayout) inflater.inflate(R.layout.song, parent,
                false);
        holder = new ViewHolder();
        holder.tvTitle = (TextView) view.findViewById(R.id.tv_song_title);
        holder.tvArtist = (TextView) view.findViewById(R.id.tv_song_artist);
        holder.imgAlbumArt = (ImageView) view
                .findViewById(R.id.img_lv_album_art);

        holder.tvArtist.setText(songs.get(position).getArtist());
        holder.tvTitle.setText(songs.get(position).getTitle());

        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }

    int id = (int) songs.get(position).getId();

    if (bitmaps == null) {
        Bitmap bm = MainActivity.getCachedArtwork(mContext,
                id, MainActivity.getDefaultArtwork(mContext));
        holder.imgAlbumArt.setImageBitmap(bm);
        bitmaps.put(id, bm);
        Log.d("inside null", "key=" + id + "bm=" + bm + "pos" + position);
    } else if (bitmaps.containsKey(id)) {
        Bitmap bm = bitmaps.get(id);
        holder.imgAlbumArt.setImageBitmap(bm);
        bitmaps.put(id, bm);
        Log.d("inside contains key", "key=" + id + "bm=" + bm + "pos"
                + position);
    } else {
        Bitmap bm = MainActivity.getCachedArtwork(mContext,
                id, MainActivity.getDefaultArtwork(mContext));

        holder.imgAlbumArt.setImageBitmap(bm);
        bitmaps.put(id, bm);
        Log.d("inside else", "key=" + id + "bm=" + bm + "pos" + position);
    }
  return view;
}
主要活动:

public static Bitmap getCachedArtwork(Context context, int artIndex,
        Bitmap defaultArtwork) {
    Bitmap d = null;
    synchronized (sArtCache) {
        d = sArtCache.get(artIndex);
    }
    if (d == null) {
        d = defaultArtwork;
        final Bitmap icon = defaultArtwork;
        int w = icon.getWidth();
        int h = icon.getHeight();
        Bitmap b = getArtworkQuick(context, artIndex, w, h);
        if (b != null) {
            d = b;// new FastBitmapDrawable(b);
            synchronized (sArtCache) {
                // the cache may have changed since we checked
                Bitmap value = sArtCache.get(artIndex);
                if (value == null) {
                    sArtCache.put(artIndex, d);
                } else {
                    d = value;
                }
            }
        }
    }
    return d;
}

// Get album art for specified album. This method will not try to
// fall back to getting artwork directly from the file, nor will
// it attempt to repair the database.
private static Bitmap getArtworkQuick(Context context, int album_id, int w, int h) {
    // NOTE: There is in fact a 1 pixel frame in the ImageView used to
    // display this drawable. Take it into account now, so we don't have to
    // scale later.
    w -= 2;
    h -= 2;
    ContentResolver res = context.getContentResolver();
    Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
    if (uri != null) {
        ParcelFileDescriptor fd = null;
        try {
            fd = res.openFileDescriptor(uri, "r");
            int sampleSize = 1;

            // Compute the closest power-of-two scale factor 
            // and pass that to sBitmapOptionsCache.inSampleSize, which will
            // result in faster decoding and better quality
            sBitmapOptionsCache.inJustDecodeBounds = true;
            BitmapFactory.decodeFileDescriptor(
                    fd.getFileDescriptor(), null, sBitmapOptionsCache);
            int nextWidth = sBitmapOptionsCache.outWidth >> 1;
            int nextHeight = sBitmapOptionsCache.outHeight >> 1;
            while (nextWidth>w && nextHeight>h) {
                sampleSize <<= 1;
                nextWidth >>= 1;
                nextHeight >>= 1;
            }

            sBitmapOptionsCache.inSampleSize = sampleSize;
            sBitmapOptionsCache.inJustDecodeBounds = false;
            Bitmap b = BitmapFactory.decodeFileDescriptor(
                    fd.getFileDescriptor(), null, sBitmapOptionsCache);

            if (b != null) {
                // finally rescale to exactly the size we need
                if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) {
                    Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true);
                    b.recycle();
                    b = tmp;
                }
            }


            return b;
        } catch (FileNotFoundException e) {
        } finally {
            try {
                if (fd != null)

                    fd.close();
            } catch (IOException e) {
            }
        }
    }
    return null;
}
public静态位图getCachedArtwork(上下文,int-artIndex,
位图(默认图形){
位图d=null;
同步(sArtCache){
d=sArtCache.get(artIndex);
}
如果(d==null){
d=默认图形;
最终位图图标=defaultArtwork;
int w=icon.getWidth();
inth=icon.getHeight();
位图b=getArtworkQuick(上下文、artIndex、w、h);
如果(b!=null){
d=b;//新的FastBitmapDrawable(b);
同步(sArtCache){
//自我们检查后,缓存可能已更改
位图值=sArtCache.get(artIndex);
如果(值==null){
sArtCache.put(artIndex,d);
}否则{
d=数值;
}
}
}
}
返回d;
}
//获取指定相册的相册艺术。此方法不会尝试
//退回到直接从文件中获取艺术品,也不会
//它试图修复数据库。
私有静态位图getArtworkQuick(上下文上下文、int相册\u id、int w、int h){
//注意:事实上,ImageView中有一个1像素的帧用于
//显示此绘图。现在将其考虑在内,这样我们就不必
//以后再缩放。
w-=2;
h-=2;
ContentResolver res=context.getContentResolver();
Uri=ContentUris.withAppendedId(sArtworkUri,唱片集id);
if(uri!=null){
ParcelFileDescriptor fd=null;
试一试{
fd=res.openFileDescriptor(uri,“r”);
int sampleSize=1;
//计算两个比例因子的最近幂
//然后将其传递给sBitmapOptionsCache.inSampleSize,它将
//导致更快的解码和更好的质量
sBitmapOptionsCache.inJustDecodeBounds=true;
BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(),null,sBitmapOptionsCache);
int nextWidth=sBitmapOptionsCache.outWidth>>1;
int nextHeight=sBitmapOptionsCache.outHeight>>1;
while(nextWidth>w&&nextHeight>h){
样本大小=1;
nextHeight>>=1;
}
sBitmapOptionsCache.inSampleSize=sampleSize;
sBitmapOptionsCache.inJustDecodeBounds=false;
位图b=BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(),null,sBitmapOptionsCache);
如果(b!=null){
//最后重新缩放到我们需要的大小
如果(sBitmapOptionsCache.outWidth!=w | | sBitmapOptionsCache.outHeight!=h){
位图tmp=Bitmap.createScaledBitmap(b,w,h,true);
b、 回收();
b=tmp;
}
}
返回b;
}catch(filenotfounde异常){
}最后{
试一试{
如果(fd!=null)
fd.close();
}捕获(IOE异常){
}
}
}
返回null;
}

在哪里设置适配器数据?可能您添加了两次项?我在Activity的onCreate方法中只设置了一次。同时,listview高度设置为仅与父项匹配。这几乎是唯一的可能性。不仅是listview,还有包含重复条目的底层数据(可以是列表或光标)。在代码中添加一些日志,这些日志会准确地显示数据中有多少项以及要添加的内容。您是对的。每次我再次使用该应用程序时,列表大小都会增加一倍。无法确定其再次添加到何处。找到错误。我已经声明列表是静态的。我的错误。谢谢你的回复。