web-dev-qa-db-ja.com

java.lang.IllegalStateException:YouTubePlayerApiの使用時にYouTubeServiceEntityが初期化されないエラー

アプリでYouTubePlayerAPIYouTubePlayerSupportFragmentを使用していますが、次のエラーが発生しますが、原因を特定できませんでした。情報を探していましたが、何も役に立ちませんでした。

_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)
_

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 (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>
_

メソッドの呼び出し:

_// 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をインスタンス化し、そのnewInstance()YouTubeオブジェクト(内部でYouTubeServiceEntityを開始します)を初期化します。方法。次に、以前にインスタンス化されたYouTubeフラグメントが、ビデオのロード中に対応するFragmentManagerFrameLayoutでアタッチされます。

ここに問題があります:ビデオがロードされる前にユーザーがアクティビティを終了すると、例外がスローされます。

その場合、ユーザーがアクティビティを終了したい場合は、どうすればよいですか?どうしたらいいのかわからない!

34
GmloMalo

繰り返しになりますが、ライフサイクルまたはコンテキストにバインドされたエンティティを操作するためにフラグメントコンストラクタまたはファクトリメソッドを使用しないでください。簡単に言えば、このようなエンティティは、super.onCreate(...)が呼び出された後にのみ使用できます。

問題は、いつinitメソッドを呼び出すかということです。

YouTubePlayerFragmentドキュメント の内容は次のとおりです。

このフラグメントに関連付けられているYouTubePlayerは、そのonDestroyView()メソッドが呼び出されるたびに解放されます。したがって、initialize(String, YouTubePlayer.OnInitializedListener)を設定してアクティビティの再作成中にフラグメントインスタンスが保持されている場合でも、このフラグメントに関連付けられたアクティビティが再作成されるたびに、setRetainInstance(boolean)を再呼び出す必要があります。

init()onActivityCreatedに入れたいと思うかもしれませんが、onStartがすでに呼び出され、レイアウトがすでに実行されているため、手遅れです。

onDestroyViewのカウンターパートはonViewCreatedであり、これが最適な候補です。

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

提案されているように、フラグメントのコンストラクターでsetRetainInstance(true)を呼び出します。アクティビティが再作成されると、フラグメントは再作成されず、そのUIのみがライフサイクルイベントを通過します。

1
Eugen Pechanec

問題は、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();
        }
      }
    }
0
beni