DeadObjectException with YouTubeThumbnailView

301 views Asked by At

I try to display a YouTubeThumbnailView in a Listview using the YouTube API, but no way to do this. I need to display a text and a video (or an image if there is no video) which requires a custom adapter and a YouTubeThumbnailView. I know there is some topic open about it but no way to fix it. (Everything works fine worthout YouTubeThumbnailView)

Here's the adapter code:

public class NewsAdapter extends BaseAdapter implements YouTubeThumbnailView.OnInitializedListener {
public static final String TAG = NewsAdapter.class.getSimpleName();

private Context mContext;
private List<News> mListNews;
private Map<View, YouTubeThumbnailLoader> mLoaders;

public NewsAdapter(Context context, List<News> list) {
    this.mListNews = list;
    this.mContext  = context;
    this.mLoaders  = new HashMap<>();
}

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

@Override
public Object getItem(int i) {
    return this.mListNews.get(i);
}

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

@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
    View v = convertView;
    Holder viewHolder;
    String videoId = mListNews.get(position).youtube_code;

    if (v == null) {
        LayoutInflater li = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = li.inflate(R.layout.item_news, null);
        viewHolder = new Holder(v);

        viewHolder.youTubePlayerView.setTag(videoId);
        viewHolder.youTubePlayerView.initialize(BuildConfigData.getKEY_API(), this);

        v.setTag(viewHolder);
    } else {
        viewHolder = (Holder) v.getTag();
        // 2) and 3) The view is already created...
        YouTubeThumbnailLoader loader = mLoaders.get(viewHolder.youTubePlayerView);
        // ...and is currently being initialized. We store the current videoId in the tag.
        if (loader == null) {
            viewHolder.youTubePlayerView.setTag(videoId);
            // ...and already initialized. Simply set the right videoId on the loader.
        } else {
            viewHolder.youTubePlayerView.setImageBitmap(null);
            loader.setVideo(videoId);
        }
    }

    if(this.mListNews.get(position).title != null) viewHolder.newsTitleTextView.setText(Html.fromHtml(mListNews.get(position).title));
    viewHolder.newsCategoryTextView.setVisibility(View.GONE);

    if(!this.mListNews.get(position).main_picture.isEmpty()) {
        final Holder finalview = viewHolder;

    return v;
}

@Override
public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
    String videoId = (String) youTubeThumbnailView.getTag();
    mLoaders.put(youTubeThumbnailView, youTubeThumbnailLoader);
    youTubeThumbnailView.setImageBitmap(null);
    youTubeThumbnailLoader.setVideo(videoId);
}

@Override
public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {

}



class Holder {
    ImageView newsImgImageView;
    TextView newsTitleTextView;
    TextView newsCategoryTextView;
    YouTubeThumbnailView youTubePlayerView;

    public Holder(View base) {
        newsImgImageView     = (ImageView) base.findViewById(R.id.news_img);
        newsTitleTextView    = (TextView) base.findViewById(R.id.news_title);
        newsCategoryTextView = (TextView) base.findViewById(R.id.news_category);
        youTubePlayerView    = (YouTubeThumbnailView) base.findViewById(R.id.youtube_player_thumb);
    }
}

and here's the stack:

java.lang.IllegalStateException: android.os.DeadObjectException
        at com.google.android.youtube.player.internal.p.a(Unknown Source)
        at com.google.android.youtube.player.internal.a.setVideo(Unknown Source)
        at com.meetphone.fabvillesdk.adapter.NewsAdapter.getView(NewsAdapter.java:85)
        at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
        at android.widget.AbsListView.obtainView(AbsListView.java:2344)
        at android.widget.ListView.makeAndAddView(ListView.java:1864)
        at android.widget.ListView.fillDown(ListView.java:698)
        at android.widget.ListView.fillGap(ListView.java:662)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4972)
        at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4516)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:549)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:211)
        at android.app.ActivityThread.main(ActivityThread.java:5317)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
 Caused by: android.os.DeadObjectException
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(Binder.java:496)
        at com.google.android.youtube.player.internal.k$a$a.a(Unknown Source)

            

Hope someone could help. Thanks all in advance             

1

There are 1 answers

0
ahmed hamdy On BEST ANSWER

If you need custom view (display video if exists or display image) I think may need to separate video view and image video with different ViewHolder

Replace your getView method into listView Adapter and create two separate getVideoView method for youtube Video view, getImageView method for image view

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

    String videoId = mListNews.get(position).youtube_code
    if (videoId.isEmpty()) {

       return getVideoView(position, convertView, viewGroup);
    } else {
       return getVideoView(position, convertView, viewGroup);
    }
}

public View getVideoView(int position, View convertView, ViewGroup viewGroup) {

    VideoViewHolder viewHolder;


    if (convertView == null || (convertView != null && convertView.getTag() instanceof VideoViewHolder)) {
        LayoutInflater li = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = li.inflate(R.layout.item_news, null);
        viewHolder  = new Holder(v);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (VideoViewHolder) convertView.getTag();
    }

    viewHolder.youTubePlayerView.setTag(videoId);
    viewHolder.youTubePlayerView.initialize(BuildConfigData.getKEY_API(), this);
    // 2) and 3) The view is already created...
    YouTubeThumbnailLoader loader = mLoaders.get(viewHolder.youTubePlayerView);
    // ...and is currently being initialized. We store the current videoId in the tag.
    if (loader == null) {
        viewHolder.youTubePlayerView.setTag(videoId);
        // ...and already initialized. Simply set the right videoId on the loader.
    } else {
        viewHolder.youTubePlayerView.setImageBitmap(null);
        loader.setVideo(videoId);
    }

    if(this.mListNews.get(position).title != null) {
        viewHolder.newsTitleTextView.setText(Html.fromHtml(mListNews.get(position).title));
    } else {
        viewHolder.newsCategoryTextView.setVisibility(View.GONE);
    } 

    return convertView;
}


public View getImageView(int position, View convertView, ViewGroup viewGroup) {

    ImageViewHolder viewHolder;

    if (convertView == null || (convertView != null && convertView.getTag() instanceof ImageViewHolder)) {
        LayoutInflater li = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = li.inflate(R.layout.item_news, null);
        viewHolder = new Holder(v);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ImageViewHolder) v.getTag();
    }

    if(this.mListNews.get(position).title != null) {
        viewHolder.newsTitleTextView.setText(Html.fromHtml(mListNews.get(position).title));
    } else {
        viewHolder.newsCategoryTextView.setVisibility(View.GONE);
    } 

    if(!this.mListNews.get(position).main_picture.isEmpty()) {
        final Holder finalview = viewHolder;

    return v;
}

modified your Holder class and create VideoViewHolder and ImageViewHolder classes

class Holder {
    ImageView newsImgImageView;
    TextView newsTitleTextView;
    TextView newsCategoryTextView;
    YouTubeThumbnailView youTubePlayerView;

    public Holder(View base) {
        newsImgImageView     = (ImageView) base.findViewById(R.id.news_img);
        newsTitleTextView    = (TextView) base.findViewById(R.id.news_title);
        newsCategoryTextView = (TextView) base.findViewById(R.id.news_category);
        youTubePlayerView    = (YouTubeThumbnailView) base.findViewById(R.id.youtube_player_thumb);
    }
}

class VideoViewHolder extends Holder {
    YouTubeThumbnailView youTubePlayerView;

    public Holder(View base) {
        super(base);
        youTubePlayerView = (YouTubeThumbnailView) base.findViewById(R.id.youtube_player_thumb);
    }
}


class ImageViewHolder extends Holder {
    ImageView newsImgImageView;

    public Holder(View base) {
        super(base);
        newsImgImageView     = (ImageView) base.findViewById(R.id.news_img);
    }
}