2014-12-20 14 views
26

Ich verwende YouTubePlayerAPI und YouTubePlayerSupportFragment in meiner app und ich die folgende Fehlermeldung bekommen, aber ich kann nicht herausfinden, was es verursacht . Ich habe nach Informationen gesucht, aber nichts Nützliches gefunden.java.lang.IllegalStateException: YouTubeServiceEntity Fehler nicht initialisiert, wenn YouTubePlayerApi mit

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) 

Im Stackstrace gibt es keine Zeilennummer, die auf eine meiner Klassen oder Aktivitäten verweist.

Irgendeine Idee davon?

Danke!

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> 

Aufruf der Methode:

EDIT

Ich habe den Ursprung dieser Fehler nicht gefunden werden. Dies ist das Szenario:

Die Aktivität beginnt. In onCreate() instanziiert es ein neues YouTubeVideoPlayerFragment und initialisiert YouTube Objekt (das die YouTubeServiceEntity intern startet) in seiner newInstance() Methode. Dann wird das YouTube Fragment, das zuvor instanziiert wurde, mit FragmentManager an das entsprechende FrameLayout während Video geladen wird.

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

Also, wenn Benutzer in diesem Fall von der Aktivität beenden möchten, was soll ich tun und wie? Ich weiß nicht wirklich was ich tun soll!

+1

können Sie Ihren Code zeigen, wo Sie YouTubeServiceEntity –

+0

Herausgegeben mit Code @Zoya – GmloMalo

+0

Leider initialisiert, aber ich bin noch nicht finde die Initialisierung von YouTubeServiceEntity. und Ihr Logcat meldet dasselbe Problem –

Antwort

0

Verwenden Sie erneut keine Fragmentkonstruktoren oder Factory-Methoden, um mit lifecycle- oder kontextgebundenen Entitäten zu arbeiten. Einfach gesagt, solche Entitäten können nur verwendet werden, nachdem super.onCreate(...) aufgerufen wurde. Die Frage ist jetzt, wann die Methode init aufgerufen werden soll?

Hier ist, was YouTubePlayerFragment documentation sagt:

Die YouTubePlayer mit diesem Fragment zugeordnet werden freigegeben, sobald seine onDestroyView() Methode aufgerufen wird. Sie müssen daher initialize(String, YouTubePlayer.OnInitializedListener) erneut aufrufen, wenn die mit diesem Fragment verknüpfte Aktivität erneut erstellt wird, selbst wenn die Fragmentinstanz bei der Neugenerierung von Aktivitäten beibehalten wird, indem setRetainInstance(boolean) festgelegt wird.

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

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

Wie vorgeschlagen Anruf setRetainInstance(true) im Konstruktor des Fragments. Wenn die Aktivität erneut erstellt wird, wird das Fragment nicht neu erstellt, nur die Benutzeroberfläche wird Lebenszyklusereignisse durchlaufen.

0

Das Problem ist die Initialisierung des Youtube-Fragments. YouTubePlayerSupportFragment muss in einer deiner Klassen erweitert werden und einige Methoden außer Kraft setzen. 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 enthalten 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(); 
     } 
     } 
    } 
Verwandte Themen