Reputation: 2051
I am using youtube api in my android app to load thumbnails for videos in my RecyclerView
. Following is my implementation in side my adapter:
private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
This holds the loaders for the YouTubeThumbnailView
for each adapter element. This is the code we use for initialisation of the YouTubeThumbnailLoader
(s):
YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(holder.thumbnail);
final String videoId = Utils.getYoutubeIdFromUrl(m.getYoutubeUrl());
holder.thumbnail.setTag(videoId);
if(loader != null) {
loader.setVideo(videoId);
}
}
When initialising the elements of the ViewHolder
, I initialise the thumbnail loaders as follows:
private void setupYoutubeThumbnail() {
thumbnail.initialize(RiyazApplication.applicationInstance
.getString(R.string.youtube_api_developer_key),
thumbnailListener);
thumbnail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v.getTag() != null && itemClickListener != null) {
itemClickListener.onClickVideo(mList.get(getAdapterPosition()));
}
}
});
and the code for releasing the thumbnail loaders is as follows:
public void releaseThumbnailLoaders() {
final Set<YouTubeThumbnailView> keysSet = thumbnailViewToLoaderMap.keySet();
for(YouTubeThumbnailView view: keysSet) {
final YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(view);
if(loader != null) {
loader.release();
}
}
thumbnailViewToLoaderMap.clear();
}
In my crashalytics, I am getting the following exception:
Fatal Exception: java.lang.IllegalStateException: YouTubeServiceEntity not initialized
at android.os.Parcel.readException(Parcel.java:1497)
at android.os.Parcel.readException(Parcel.java:1443)
at com.google.android.youtube.player.internal.l$a$a.a(Unknown Source)
at com.google.android.youtube.player.internal.o.a(Unknown Source)
at com.google.android.youtube.player.internal.p.(Unknown Source)
at com.google.android.youtube.player.internal.ac.a(Unknown Source)
at com.google.android.youtube.player.YouTubeThumbnailView$a.a(Unknown Source)
at com.google.android.youtube.player.internal.r.g(Unknown Source)
at com.google.android.youtube.player.internal.r$c.a(Unknown Source)
at com.google.android.youtube.player.internal.r$b.a(Unknown Source)
at com.google.android.youtube.player.internal.r$a.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5052)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(NativeStart.java)
I am not sure, why am I getting this. Can anyone please help?
Upvotes: 4
Views: 904
Reputation: 1982
Put your initaizle statement in a try-catch statement like so:
try {
thumbnail.initialize(RiyazApplication.applicationInstance.getString(R.string.youtube_api_developer_key), thumbnailListener);
}
catch(IllegalStateException w){}
Upvotes: 1
Reputation: 1748
Please check the below code. I am using a static video list to populate in RecyclerView. Below code has been implemented using RecyclerView in activity.
Activity:-
public class YouTubeVideoListActivity extends AppCompatActivity {
private RecyclerView recyclerViewList;
private RecyclerAdapter adapter;
private static final List<VideoEntry> VIDEO_LIST;
static {
List<VideoEntry> list = new ArrayList<VideoEntry>();
list.add(new VideoEntry("YouTube Collection", "Y_UmWdcTrrc"));
list.add(new VideoEntry("GMail Tap", "1KhZKNZO8mQ"));
list.add(new VideoEntry("Chrome Multitask", "UiLSiqyDf4Y"));
list.add(new VideoEntry("Google Fiber", "re0VRK6ouwI"));
list.add(new VideoEntry("Autocompleter", "blB_X38YSxQ"));
list.add(new VideoEntry("GMail Motion", "Bu927_ul_X0"));
list.add(new VideoEntry("Translate for Animals", "3I24bSteJpw"));
VIDEO_LIST = Collections.unmodifiableList(list);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_you_tube_video_list);
recyclerViewList=findViewById(R.id.recyclerViewList);
adapter = new RecyclerAdapter(this, VIDEO_LIST);
recyclerViewList.setLayoutManager(new LinearLayoutManager(this));
recyclerViewList.setAdapter(adapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
adapter.releaseLoaders();
}
}
Model class:-
public class VideoEntry {
private final String text;
private final String videoId;
public VideoEntry(String text, String videoId) {
this.text = text;
this.videoId = videoId;
}
public String getText() {
return text;
}
public String getVideoId() {
return videoId;
}
}
Recycler Adapter:-
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<VideoEntry> entries;
private final List<View> entryViews;
private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
private final LayoutInflater inflater;
private final ThumbnailListener thumbnailListener;
private boolean labelsVisible;
private Context context;
public RecyclerAdapter(Context context,List<VideoEntry> entries) {
this.entries = entries;
this.context = context;
entryViews = new ArrayList<>();
thumbnailViewToLoaderMap = new HashMap<>();
inflater = LayoutInflater.from(context);
thumbnailListener = new ThumbnailListener();
labelsVisible = true;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.you_tube_row, parent, false);
return new Holder(view);
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
final Holder h = (Holder) holder;
VideoEntry entry = entries.get(position);
YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(h.thumbnail);
if (loader == null) {
// 2) The view is already created, and is currently being initialized. We store the
// current videoId in the tag.
h.thumbnail.setTag(entry.getVideoId());
} else {
// 3) The view is already created and already initialized. Simply set the right videoId
// on the loader.
h.thumbnail.setImageResource(R.drawable.loading_thumbnail);
loader.setVideo(entry.getVideoId());
}
h.label.setText(entry.getText());
h.label.setVisibility(labelsVisible ? View.VISIBLE : View.GONE);
}
@Override
public int getItemCount() {
return entries.size();
}
@Override
public long getItemId(int position) {
return 0;
}
public void releaseLoaders() {
for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap.values()) {
loader.release();
}
}
public void setLabelVisibility(boolean visible) {
labelsVisible = visible;
for (View view : entryViews) {
view.findViewById(R.id.text).setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
class Holder extends RecyclerView.ViewHolder {
TextView label;
YouTubeThumbnailView thumbnail;
Holder(final View itemView) {
super(itemView);
label = itemView.findViewById(R.id.text);
thumbnail = itemView.findViewById(R.id.thumbnail);
thumbnail.initialize(DEVELOPER_KEY, thumbnailListener);
}
}
private final class ThumbnailListener implements
YouTubeThumbnailView.OnInitializedListener,
YouTubeThumbnailLoader.OnThumbnailLoadedListener {
@Override
public void onInitializationSuccess(
YouTubeThumbnailView view, YouTubeThumbnailLoader loader) {
loader.setOnThumbnailLoadedListener(this);
thumbnailViewToLoaderMap.put(view, loader);
view.setImageResource(R.drawable.loading_thumbnail);
String videoId = (String) view.getTag();
loader.setVideo(videoId);
}
@Override
public void onInitializationFailure(
YouTubeThumbnailView view, YouTubeInitializationResult loader) {
view.setImageResource(R.drawable.no_thumbnail);
}
@Override
public void onThumbnailLoaded(YouTubeThumbnailView view, String videoId) {
}
@Override
public void onThumbnailError(YouTubeThumbnailView view, YouTubeThumbnailLoader.ErrorReason errorReason) {
view.setImageResource(R.drawable.no_thumbnail);
}
}
}
Recycler list row layout (you_tube_row.xml):-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="95dp"
android:orientation="horizontal"
android:gravity="center"
android:background="?android:attr/activatedBackgroundIndicator">
<com.google.android.youtube.player.YouTubeThumbnailView
android:id="@+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/no_thumbnail"
android:adjustViewBounds="true"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#fff"/>
</LinearLayout>
If you want more detail you can download sample code from here.
Upvotes: 0