web-dev-qa-db-de.com

java.lang.IllegalStateException: YouTubeServiceEntity nicht initialisierter Fehler bei Verwendung von YouTubePlayerApi

Ich verwende YouTubePlayerAPI und YouTubePlayerSupportFragment in meiner App und erhalte die folgende Fehlermeldung, konnte aber nicht herausfinden, was die Ursache ist. Ich habe nach Informationen gesucht, aber nichts Nützliches gefunden.

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$a.a(Unknown Source)
    at com.google.Android.youtube.player.internal.o.a(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.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: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)

In der Stapelspur gibt es keine Zeilennummer, die auf eine meiner Klassen oder Aktivitäten verweist.

Irgendeine Idee davon?

Vielen Dank!

EDIT

Meine benutzerdefinierte YoutubePlayerFragment Klasse: 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 (e.g. 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>

aufrufmethode:

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

EDIT

Ich habe den Ursprung dieses Fehlers herausgefunden. Dies ist das Szenario:

Die Aktivität beginnt. In onCreate() instanziiert es eine neue YouTubeVideoPlayerFragment und initialisiert YouTube object (das die YouTubeServiceEntity intern startet) in seiner newInstance() -Methode. Anschließend wird das zuvor instanziierte YouTube-Fragment mit FragmentManager an die entsprechende FrameLayout angehängt, während das Video geladen wird.

Hier ist das Problem: Wenn der Benutzer die Aktivität verlässt, bevor das Video geladen wurde, wird die Ausnahme ausgelöst.

Wenn der Benutzer in diesem Fall die Aktivität beenden möchte, was soll ich dann tun und wie? Ich weiß nicht wirklich was ich tun soll!

31
GmloMalo

Verwenden Sie erneut KEINE Fragmentkonstruktoren oder Factory-Methoden, um mit Lebenszyklus- oder kontextgebundenen Entitäten zu arbeiten. Einfach ausgedrückt, solche Entitäten können nur verwendet werden, nachdem super.onCreate(...) aufgerufen wurde.

Die Frage ist nun, wann die Methode init aufzurufen ist.

Hier ist was YouTubePlayerFragment Dokumentation sagt:

Die diesem Fragment zugeordnete YouTubePlayer wird immer dann freigegeben, wenn ihre onDestroyView() -Methode aufgerufen wird. Sie müssen daher initialize(String, YouTubePlayer.OnInitializedListener) immer dann erneut aufrufen, wenn die mit diesem Fragment verknüpfte Aktivität erneut erstellt wird, auch wenn die Fragmentinstanz während der erneuten Erstellung der Aktivität beibehalten wird, indem Sie setRetainInstance(boolean) festlegen.

Sie könnten versucht sein, init() in onActivityCreated zu setzen, aber das ist zu spät, da onStart bereits aufgerufen und das Layout bereits ausgeführt wurde.

Gegenstück zu onDestroyView ist onViewCreated und das ist der perfekte Kandidat.

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

Rufen Sie wie vorgeschlagen setRetainInstance(true) im Konstruktor des Fragments auf. Wenn die Aktivität neu erstellt wird, wird das Fragment nicht neu erstellt, sondern nur die Benutzeroberfläche durchläuft Lebenszyklusereignisse.

1
Eugen Pechanec

Das Problem ist die Initialisierung des Youtube-Fragments. YouTubePlayerSupportFragment muss in einer Klasse von Ihnen erweitert werden und setzt einige Methoden außer Kraft. Sie müssen die Bildschirmausrichtung und den onSaveInstanceState steuern.

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

Aktivität mit Youtube Fragment

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