当setRaetainInstance(true)时,Youtube泄露服务连接

时间:2015-04-26 09:46:06

标签: android youtube-api

我遇到以下错误:

04-26 11:41:58.662: E/ActivityThread(10933): Activity MyActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@2cf388d that was originally bound here

我有一个片段,我在onCreate中设置了以下内容:

/**
 * 
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.setRetainInstance(true);
}

我设置这个因为我有一个youtubevideos列表与缩略图,我不 希望每次用户旋转屏幕时重新加载这些缩略图。 这只是不必要的流量。

以下是我对listview的适配器:

public class YoutubeListAdapter extends BaseAdapter {
    private List<TutorialEntry> entries = null;
    private List<View> entryViews = null;
    private Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap = null;
    private LayoutInflater inflater = null;
    private TutorialThumbnailListener thumbnailListener = null;
    private boolean labelsVisible = false;;

    public YoutubeListAdapter(Context context, List<TutorialEntry> entries) {
        this.entries = entries;
        this.entryViews = new ArrayList<View>();
        this.thumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>();
        this.inflater = LayoutInflater.from(context);
        this.thumbnailListener = new TutorialThumbnailListener(this.thumbnailViewToLoaderMap);
        this.labelsVisible = true;
    }

    @Override
    public int getCount() {
        return this.entries.size();
    }

    @Override
    public TutorialEntry getItem(int position) {
        return entries.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TutorialEntry entry = entries.get(position);

        ViewHolder holder = null;

        if (convertView == null) {
            convertView = this.inflater.inflate(R.layout.fragment_tutorials_row, parent, false);

            holder = new ViewHolder();
            holder.thumbnail = (YouTubeThumbnailView) convertView.findViewById(R.id.tutorials_row_thumbnail);
            holder.thumbnail.setTag(entry.getVideoId());
            holder.thumbnail.initialize(Globals.GOOGLE_API_KEY, this.thumbnailListener);
            holder.textViewTitle = (TextView) convertView.findViewById(R.id.tutorials_row_title);

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

            YouTubeThumbnailLoader loader = this.thumbnailViewToLoaderMap.get(holder.thumbnail);

            if (loader == null) {
                holder.thumbnail.setTag(entry.getVideoId());
            } else {
                holder.thumbnail.setImageResource(R.drawable.youtube_loading_thumbnail);

                loader.setVideo(entry.getVideoId());
            }
        }

        holder.textViewTitle.setText(entry.getTitle());
        holder.textViewTitle.setVisibility(labelsVisible ? View.VISIBLE : View.GONE);

        return convertView;
    }

    public void releaseLoaders() {
        for (YouTubeThumbnailLoader loader : this.thumbnailViewToLoaderMap.values()) {
            loader.release();
        }
    }

    public void setLabelVisibility(boolean labelsVisible) {
        this.labelsVisible = labelsVisible;

        for (View view : this.entryViews) {
            view.findViewById(R.id.tutorials_row_title).setVisibility(labelsVisible ? View.VISIBLE : View.GONE);
        }
    }

    private static class ViewHolder {
        private YouTubeThumbnailView thumbnail = null;
        private TextView textViewTitle = null;
    }
}

问题出现在这一行:

holder.thumbnail.initialize(Globals.GOOGLE_API_KEY, this.thumbnailListener);

有人可以帮助我了解那里发生了什么,以及我如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

此异常通常来自不释放所有加载器。从我所知道的,你永远不会调用你的releaseLoaders()方法,因为当活动被拆除时,加载器只是坐在那里。 Android的设计方式,您应该释放这些加载器,否则会导致内存泄漏。

就个人而言,我将我的加载器版本放在我的onstop()方法中,并且它的工作非常精细。

@Override
public void onStop() {
    super.onStop();
    for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap.values()) {
        loader.release();
    }
}