Java.lang.IllegalStateException: YouTubeServiceEntity не инициализировала ошибку при использовании YouTubePlayerApi

Я использую YouTubePlayerAPI и YouTubePlayerSupportFragment в своем приложении, и я получаю следующую ошибку, но я не мог узнать, что вызывает ее. Я искал информацию, но я не нашел ничего полезного.

java.lang.IllegalStateException: YouTubeServiceEntity not initialized at android.os.Parcel.readException(Parcel.java:1433) at android.os.Parcel.readException(Parcel.java:1379) at com.google.android.youtube.player.internal.l$a$aa(Unknown Source) at com.google.android.youtube.player.internal.oa(Unknown Source) at com.google.android.youtube.player.internal.ad.a(Unknown Source) at com.google.android.youtube.player.YouTubePlayerView.a(Unknown Source) at com.google.android.youtube.player.YouTubePlayerView$1.a(Unknown Source) at com.google.android.youtube.player.internal.rg(Unknown Source) at com.google.android.youtube.player.internal.r$ca(Unknown Source) at com.google.android.youtube.player.internal.r$ba(Unknown Source) at com.google.android.youtube.player.internal.r$a.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method) 

В stackstrace нет никакого номера строки, указывающего на любой из моих классов или действий.

Любая идея?

Благодаря!

РЕДАКТИРОВАТЬ

Мой пользовательский класс YoutubePlayerFragment : YouTubeVideoPlayerFragment.java

 public class YouTubeVideoPlayerFragment extends YouTubePlayerSupportFragment { private static final String ARG_URL = "url"; // =========================================================== // Constructors // =========================================================== /** * Mandatory empty constructor for the fragment manager to instantiate the * fragment (eg upon screen orientation changes). */ public YouTubeVideoPlayerFragment() { } /** * Factory method to generate a new instance of the fragment given a video URL. * * @param url The video url this fragment represents * @return A new instance of this fragment with itemId extras */ public static YouTubeVideoPlayerFragment newInstance(String url) { final YouTubeVideoPlayerFragment mFragment = new YouTubeVideoPlayerFragment(); // Set up extras final Bundle args = new Bundle(); args.putString(ARG_URL, url); mFragment.setArguments(args); // Initialize YouTubePlayer mFragment.init(); return mFragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } private void init(){ initialize(Constants.API_KEY, new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean wasRestored) { if (!wasRestored) { youTubePlayer.cueVideo(getArguments().getString(ARG_URL)); youTubePlayer.setShowFullscreenButton(false); } } } 

fragment.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_height="match_parent" android:layout_width="match_parent" android:background="@color/black" > <!-- For YoutubeFragment --> <FrameLayout android:id="@+id/youtube_fragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

Метод вызова:

 // Create a new instance of YouTubeVideoPlayerFragment providing video id // and place it in the corresponding FrameLayout final YouTubeVideoPlayerFragment youTubeVideoPlayerFragment = YouTubeVideoPlayerFragment.newInstance(VIDEO_ID); final FragmentTransaction ft = getChildFragmentManager().beginTransaction(); ft.replace(R.id.youtube_fragment, youTubeVideoPlayerFragment); ft.commit(); 

РЕДАКТИРОВАТЬ

Я выяснил происхождение этой ошибки. Это сценарий:

Действие начинается. В onCreate() он создает новый YouTubeVideoPlayerFragment и инициализирует объект YouTube (который запускает YouTubeServiceEntity внутри) в своем методе newInstance() . Затем фрагмент YouTube который был создан ранее, прикрепляется с помощью FragmentManager к соответствующему FrameLayout во время загрузки видео.

Вот в чем проблема: если пользователь выходит из операции до загрузки видео, исключение вызывается.

Итак, если пользователь хочет выйти из действия в этом случае, что мне делать и как? Я не знаю, что делать!

Solutions Collecting From Web of "Java.lang.IllegalStateException: YouTubeServiceEntity не инициализировала ошибку при использовании YouTubePlayerApi"

Еще раз НЕ используйте конструкторы фрагментов или фабричные методы для работы с объектами, связанными с жизненным циклом или контекстом. Проще говоря, такие объекты могут использоваться только после super.onCreate(...) .

Вопрос в том, когда вызывать метод init ?

Вот что говорит документация YouTubePlayerFragment :

YouTubePlayer связанный с этим фрагментом, будет выпущен всякий раз, когда onDestroyView() его onDestroyView() . Поэтому вам придется повторно initialize(String, YouTubePlayer.OnInitializedListener) всякий раз, когда активность, связанная с этим фрагментом, воссоздается, даже если экземпляр фрагмента сохраняется при повторном создании активности, устанавливая setRetainInstance(boolean) .

У вас может возникнуть соблазн поместить init() в onActivityCreated но это слишком поздно, так как onStart уже был вызван, и макет уже выполнен.

Counterpart onDestroyViewonViewCreated и это идеальный кандидат.

 @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); init(); } 

Как предложил вызов setRetainInstance(true) в конструкторе фрагмента. Когда активность будет воссоздана, фрагмент не будет воссоздан, только его пользовательский интерфейс будет проходить события жизненного цикла.

Проблема заключается в инициализации фрагмента Youtube. YouTubePlayerSupportFragment должен быть расширен в вашем классе и переопределяет некоторые методы. Вы должны контролировать ориентацию экрана и onSaveInstanceState.

 public class YouTubePlayerFragment extends YouTubePlayerSupportFragment { private YouTubePlayer mPlayer; public static YouTubePlayerFragment newInstance() { return new YouTubePlayerFragment(); } @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); setRetainInstance(true); } @Override public void initialize(String s, YouTubePlayer.OnInitializedListener onInitializedListener) { super.initialize(s, new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) { mPlayer = youTubePlayer; onInitializedListener.onInitializationSuccess(provider, youTubePlayer, b); } @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { onInitializedListener.onInitializationFailure(provider, youTubeInitializationResult); } }); } @Override public void onDestroyView() { if (mPlayer != null) { mPlayer.release(); } super.onDestroyView(); } public YouTubePlayer getPlayer() { return mPlayer; } } 

YoutubeFragment.class

  public class YoutubeFragment extends Fragment { private static final String EXTRA_PLAYED_VIDEO = "EXTRA_PLAYED_VIDEO"; private static final String EXTRA_IS_PLAYING = "EXTRA_IS_PLAYING"; private static final String YOUTUBE_FRAGMENT = "YOUTUBE_FRAGMENT"; private static final String EXTRA_YOUTUBE_ID = "EXTRA_YOUTUBE_ID"; private RelativeLayout youtubeLayoutContainer; private String youtubeId; private int playedVideo; private boolean isPlaying; YouTubePlayer.OnInitializedListener onInitializedListener = new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) { if (!wasRestored) { setYouTubePlayer(player); } } @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult error) { } }; public static YoutubeFragment newInstance(String youtubeId) { YoutubeFragment youtubeElements = new YoutubeFragment(); Bundle bundle = new Bundle(); bundle.putString(EXTRA_YOUTUBE_ID, youtubeId); youtubeElements.setArguments(bundle); return youtubeElements; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View mView = inflater.inflate(R.layout.view_youtube_elements_item, container, false); initViews(mView); initYoutubeFragment(); return mView; } private void initViews(View view) { youtubeLayoutContainer = (RelativeLayout) view.findViewById(R.id.youtubeLayoutContainer); youtubeLayoutContainer.getViewTreeObserver() .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onGlobalLayout() { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT); youtubeLayoutContainer.setLayoutParams(lp); if (AndroidSdkVersion.hasJellyBean16()) { youtubeLayoutContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this); } } }); } private void initYoutubeFragment() { try { YouTubePlayerFragment youTubePlayerFragment2 = YouTubePlayerFragment.newInstance(); youTubePlayerFragment2.initialize(BuildConfig.YOUTUBE_DEVELOPER_KEY, onInitializedListener); if (this.getActivity() != null && !this.getActivity().isFinishing()) { getChildFragmentManager().beginTransaction() .replace(R.id.youtubePlayerFragmentContent, youTubePlayerFragment2, YOUTUBE_FRAGMENT) .commitAllowingStateLoss(); } } catch (Exception ignored) { } } public void setYouTubePlayer(final YouTubePlayer player) { try { if (player == null) { return; } player.setShowFullscreenButton(true); player.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT); if (playedVideo >= 0) { if (playedVideo == 0 || isPlaying) { player.loadVideo(youtubeId, playedVideo); } else { player.cueVideo(youtubeId, playedVideo); } } } catch (Exception ignored) { } } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState != null) { playedVideo = savedInstanceState.getInt(EXTRA_PLAYED_VIDEO); isPlaying = savedInstanceState.getBoolean(EXTRA_IS_PLAYING); } } @Override public void onSaveInstanceState(Bundle outState) { try { YouTubePlayerFragment youTubePlayerSupportFragment = (YouTubePlayerFragment) getChildFragmentManager().findFragmentByTag(YOUTUBE_FRAGMENT); YouTubePlayer mPlayer = youTubePlayerSupportFragment.getPlayer(); if (mPlayer != null) { outState.putInt(EXTRA_PLAYED_VIDEO, mPlayer.getCurrentTimeMillis()); outState.putBoolean(EXTRA_IS_PLAYING, mPlayer.isPlaying()); } } catch (Exception ignored) { } super.onSaveInstanceState(outState); } } 

Активность, содержащая фрагмент Youtube

 public class YoutubeContentDataActivity extends BaseActivity { private static final String EXTRA_YOUTUBE_VIDEO_ID = "EXTRA_YOUTUBE_VIDEO_ID"; private static final String TAG_RETAINED_FRAGMENT = "TAG_RETAINED_FRAGMENT"; public static void open(Context context, String videoId) { Intent intent = new Intent(context, YoutubeContentDataActivity.class); intent.putExtra(EXTRA_YOUTUBE_VIDEO_ID, videoId); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_youtube_main_container_layout); FragmentManager fm = getSupportFragmentManager(); YoutubeFragment youtubeElementsFragment = (YoutubeFragment) fm.findFragmentByTag(TAG_RETAINED_FRAGMENT); // create the fragment and data the first time if (youtubeElementsFragment == null) { String videoId = getIntent().getStringExtra(EXTRA_YOUTUBE_VIDEO_ID); // videoId = "17uHCHfgs60";//"ikO91fQBsTQ"; youtubeElementsFragment = YoutubeFragment.newInstance(videoId); FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.youtube_main_container, youtubeElementsFragment, TAG_RETAINED_FRAGMENT) .commit(); } } @Override public void onPause() { super.onPause(); if (isFinishing()) { FragmentManager fm = getSupportFragmentManager(); YoutubeFragment youtubeElementsFragment = (YoutubeFragment) fm.findFragmentByTag(TAG_RETAINED_FRAGMENT); fm.beginTransaction().remove(youtubeElementsFragment).commit(); } } }