Android java.lang.IllegalStateException:YouTubeServiceEntity未初始化使用YouTubePlayerApi时出错
我正在我的应用程序中使用YouTubePlayerAPI和YouTubePlayerSupportFragment,我发现以下错误,但我无法找出原因。我一直在寻找信息,但没有找到任何有用的Android java.lang.IllegalStateException:YouTubeServiceEntity未初始化使用YouTubePlayerApi时出错,android,youtube-api,Android,Youtube Api,我正在我的应用程序中使用YouTubePlayerAPI和YouTubePlayerSupportFragment,我发现以下错误,但我无法找出原因。我一直在寻找信息,但没有找到任何有用的 java.lang.IllegalStateException: YouTubeServiceEntity not initialized at android.os.Parcel.readException(Parcel.java:1433) at android.os.Parcel.rea
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中没有任何行号指向我的任何课程或活动
你知道吗
谢谢
编辑
我的自定义YoutubePlayerFragmentClass: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>
编辑
我已经找到了那个错误的根源。这是一个场景:
活动开始了。在onCreate()
中,它实例化一个新的YouTubeVideoPlayerFragment
并在其newInstance()
方法中初始化YouTube对象(该对象在内部启动youtubeserviceinty
)。然后,在加载视频时,之前实例化的YouTube
片段将与FragmentManager
一起附加到相应的FrameLayout
问题是:如果用户在加载视频之前退出活动,将引发异常
所以,如果用户想退出这种情况下的活动,我应该怎么做,怎么做?我真的不知道该怎么办 再次强调,不要使用片段构造函数或工厂方法来处理生命周期或上下文绑定的实体。简单地说,只有在调用了
super.onCreate(…)
之后才能使用这些实体
现在的问题是,何时调用init
方法
下面是我所说的:
每当调用其onDestroyView()
方法时,将释放与此片段关联的youtubeplyer
。因此,每当重新创建与此片段关联的活动时,您必须重新调用initialized(String,YouTubePlayer.OnInitializedListener)
,即使通过设置setRetainInstance(布尔值)
在整个活动重新创建过程中保留片段实例
您可能想将init()
放在onActivityCreated
中,但那太晚了,因为已经调用了onStart
,并且已经执行了布局
与onDestroyView相对应的是创建的OnView
,这是一个完美的候选者
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init();
}
正如建议的那样,在片段的构造函数中调用setRetainInstance(true)。重新创建活动时,将不会重新创建片段,只有其UI将经历生命周期事件。问题在于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();
}
}
}
这段代码是用xamarin.android编写的,应该有帮助
public class PlayerActivity : YouTubeBaseActivity, IYouTubePlayerOnInitializedListener, IYouTubePlayerPlayerStateChangeListener
{
private int RECOVERY_DIALOG_REQUEST = 1;
public static string DEVELOPER_KEY = "key";
IYouTubePlayer player;
// public static string VIDEO_ID = "_OBlgSz8sSM";
public void OnInitializationFailure(IYouTubePlayerProvider p0, YouTubeInitializationResult p1)
{
if (p1.IsUserRecoverableError)
{
p1.GetErrorDialog(this, RECOVERY_DIALOG_REQUEST).Show();
}
else
{
string errorMessage = string.Format(
"ERROR", p1.ToString());
Toast.MakeText(this, errorMessage, ToastLength.Long).Show();
}
}
public void OnInitializationSuccess(IYouTubePlayerProvider p0, IYouTubePlayer p1, bool p2)
{
// YouTubeItem item = JsonConvert.DeserializeObject<YouTubeItem>(Intent.GetStringExtra("VideoID"));
YouTubeItem itrm = new YouTubeItem();
itrm.VideoId = Intent.GetStringExtra("VideoID2");
string VIDEO_ID = itrm.VideoId;
p1.LoadVideo(VIDEO_ID);
player = p1;
p1.SetPlayerStateChangeListener(this);
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.PlayerLayout);
YouTubePlayerView youTubeView = FindViewById<YouTubePlayerView>(Resource.Id.youtubeView);
youTubeView.Initialize(DEVELOPER_KEY, this);
// Create your application here
}
public void OnAdStarted()
{
}
public void OnError(YouTubePlayerErrorReason p0)
{
}
public void OnLoaded(string p0)
{
}
public void OnLoading()
{
}
public void OnVideoEnded()
{
}
}
public void OnVideoStarted()
{
}
public class PlayerActivity:YouTubeBaseActivity、IYouTubePlayerOnInitializedListener、IYouTubePlayerPlayerStateChangeListener
{
专用int恢复对话框请求=1;
publicstaticstringdeveloper\u KEY=“KEY”;
IYouTubePlayer播放器;
//公共静态字符串视频_ID=“_OBlgSz8sSM”;
初始化失败时的公共无效(IYouTubePlayerProvider p0,YouTubeInitializationResult p1)
{
如果(p1.IsUserRecoverableError)
{
p1.GetErrorDialog(这是恢复对话框请求).Show();
}
其他的
{
string errorMessage=string.Format(
“错误”,p1.ToString());
Toast.MakeText(this,errorMessage,ToastLength.Long).Show();
}
}
初始化成功时的公共无效(IYOUTUBEPPLAYER提供程序p0、IYOUTUBEPPLAYER p1、bool p2)
{
//YouTubeItem=JsonConvert.DeserializeObject(Intent.GetStringExtra(“VideoID”);
YouTubeItem itrm=新的YouTubeItem();
itrm.VideoId=Intent.GetStringExtra(“VideoID2”);
字符串VIDEO_ID=itrm.VideoId;
p1.加载视频(视频_ID);
播放器=p1;
p1.SetPlayerStateChangeListener(此);
}
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.PlayerLayout);
YouTubePlayerView youTubeView=findviewbyd(Resource.Id.youTubeView);
初始化(开发者密钥,此);
//在此处创建应用程序
}
在开始时的公共无效()
{
}
公共无效报告人(YouTubePlayerRorrorReason p0)
{
}
已加载公共void(字符串p0)
{
}
公共无效加载()
{
}
公开作废已结束()
{
}
}
公共void OnVideoStarted()
{
}
我看到华为手机报告了相同的错误
我在这里看到一种解释:
不确定我们的代码中是否有捕获异常的方法。能否显示您初始化YouTube服务实体的代码,使用code@ZoyaSorry编辑,但我仍然无法找到YouTube服务实体的初始化。你的logcat也报告了同样的问题抱歉!我不直接初始化YouTube服务实体。我想它是在YouTubePlayerApi jar库中初始化的,我正在使用Youtube api,并且非常面临这个错误。你找到解决方案了吗?我只在YouTube player上使用了activity,但我还是从谷歌控制台收到了一些关于这个问题的报告:
java.lang.IllegalStateException android.os.Parcel.readException
。所以这与片段无关(我不使用它们),我正在从onResume()调用init(),仍然会发生崩溃。知道吗?我在onViewCreated中调用init()并得到相同的结果bug@Duna看起来保存状态有问题。通过转到开发人员设置和
public class PlayerActivity : YouTubeBaseActivity, IYouTubePlayerOnInitializedListener, IYouTubePlayerPlayerStateChangeListener
{
private int RECOVERY_DIALOG_REQUEST = 1;
public static string DEVELOPER_KEY = "key";
IYouTubePlayer player;
// public static string VIDEO_ID = "_OBlgSz8sSM";
public void OnInitializationFailure(IYouTubePlayerProvider p0, YouTubeInitializationResult p1)
{
if (p1.IsUserRecoverableError)
{
p1.GetErrorDialog(this, RECOVERY_DIALOG_REQUEST).Show();
}
else
{
string errorMessage = string.Format(
"ERROR", p1.ToString());
Toast.MakeText(this, errorMessage, ToastLength.Long).Show();
}
}
public void OnInitializationSuccess(IYouTubePlayerProvider p0, IYouTubePlayer p1, bool p2)
{
// YouTubeItem item = JsonConvert.DeserializeObject<YouTubeItem>(Intent.GetStringExtra("VideoID"));
YouTubeItem itrm = new YouTubeItem();
itrm.VideoId = Intent.GetStringExtra("VideoID2");
string VIDEO_ID = itrm.VideoId;
p1.LoadVideo(VIDEO_ID);
player = p1;
p1.SetPlayerStateChangeListener(this);
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.PlayerLayout);
YouTubePlayerView youTubeView = FindViewById<YouTubePlayerView>(Resource.Id.youtubeView);
youTubeView.Initialize(DEVELOPER_KEY, this);
// Create your application here
}
public void OnAdStarted()
{
}
public void OnError(YouTubePlayerErrorReason p0)
{
}
public void OnLoaded(string p0)
{
}
public void OnLoading()
{
}
public void OnVideoEnded()
{
}
}
public void OnVideoStarted()
{
}