【问题标题】:java.lang.IllegalStateException: YouTubeServiceEntity not initialized with YouTubeThumbnailViewjava.lang.IllegalStateException:未使用 YouTubeThumbnailView 初始化 YouTubeServiceEntity
【发布时间】:2019-01-05 06:05:43
【问题描述】:

我在我的 android 应用程序中使用 youtube api 来为我的 RecyclerView 中的视频加载缩略图。以下是我在适配器中的实现:

private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;

这包含每个适配器元素的YouTubeThumbnailView 的加载器。这是我们用于初始化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);
                    }
                }

在初始化ViewHolder的元素时,我初始化缩略图加载器如下:

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()));
                    }
                }
            });

以及释放缩略图加载器的代码如下:

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();
    }

在我的 crashalytics 中,我收到以下异常:

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)

我不确定,为什么我会得到这个。有人可以帮忙吗?

【问题讨论】:

  • 您好,YouTube 播放器与加载视频缩略图有什么关系?这两件事应该分开。
  • @Pierfran 看看第 8 个堆栈跟踪。堆栈跟踪中提到了缩略图视图。
  • 为什么不使用 YouTube 数据 API 下载缩略图并将其显示在图像视图中?
  • 嗯..我没试过,但这应该也没有问题吧?
  • YouTubeServiceEntity的代码在哪里

标签: android youtube-api illegalstateexception android-youtube-api


【解决方案1】:

将您的 initaizle 语句放在 try-catch 语句中,如下所示:

try {   
 
  thumbnail.initialize(RiyazApplication.applicationInstance.getString(R.string.youtube_api_developer_key), thumbnailListener);
} 
catch(IllegalStateException w){}

【讨论】:

    【解决方案2】:

    请检查以下代码。我正在使用静态视频列表填充 RecyclerView。下面的代码是在activity中使用RecyclerView实现的。

    活动:-

    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();
    }
    
    }
    

    模型类:-

    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;
    }
    }
    

    回收适配器:-

    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);
        }
    }
    }
    

    回收站列表行布局(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>
    

    如果您想了解更多详细信息,可以从here 下载示例代码。

    【讨论】:

    • 我使用了来自谷歌的类似示例并编写了代码。如果您阅读我的代码...与您在此处提到的相同。我看不出有什么不同...您能指出您注意到的一些事情吗?
    • 你在 Fragment 中有 RecyclerView 吗?
    • 是的..我在片段中使用它
    • 确保您在片段的 onDestroyView 方法中释放加载器。
    • 是这个问题吗?
    猜你喜欢
    • 2015-02-19
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2012-08-12
    • 2019-09-25
    • 2020-10-07
    相关资源
    最近更新 更多