集成Google Cast时遇Task is not yet complete异常的解决方法
问题
我在一个架构不佳的Java代码库中集成Google Cast,参考官方CastVideos-android项目实现,耗时数周。现在卡在mCastContext = CastContext.getSharedInstance(this,localExecutor).getResult();这句代码上,运行时抛出异常:
Unable to start activity ComponentInfo{}: java.lang.IllegalStateException: Task is not yet complete
已尝试添加参考项目中的相关代码,但问题仍未解决。以下是关键代码片段:
VideoExoPlayerActivity 核心代码
public class VideoExoPlayerActivity extends BaseActivity implements OnClickHandlerInterface { private CastContext mCastContext; private SessionManager mSessionManager; private SessionManagerListener<CastSession> mSessionManagerListener = new SessionManagerListenerImpl(); private Executor localExecutor = Executors.newSingleThreadExecutor(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_video_exo_player); viewModel = new ViewModelProvider(this, new CommonFactory<>(this)).get(VideoPlayerViewModel.class); // 抛出异常的代码 mCastContext = CastContext.getSharedInstance(this, localExecutor).getResult(); initView(); hideStatusBar(); startService(new Intent(this, HistoryAPIBackgroundService.class)); } }
VideoBrowserActivity 核心代码
public class VideoBrowserActivity extends AppCompatActivity { private CastContext mCastContext; private CastStateListener mCastStateListener; private Executor localExecutor = Executors.newSingleThreadExecutor(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.video_browser); setupActionBar(); mCastStateListener = new CastStateListener() { @Override public void onCastStateChanged(int newState) { if (newState != CastState.NO_DEVICES_AVAILABLE) { showIntroductoryOverlay(); } } }; // 同样抛出异常的代码 mCastContext = CastContext.getSharedInstance(this,localExecutor).getResult(); } }
解决方案
核心问题是CastContext.getSharedInstance()返回的是ListenableFuture异步任务,直接调用getResult()会因为任务未完成抛出异常。必须改用异步回调的方式处理:
- 替换同步获取逻辑,用
addCallback等待任务完成后再初始化Cast组件 - 将Cast相关的后续初始化逻辑(如Session监听、MediaRouteButton设置)移到回调中
- 补充生命周期管理,在
onStart/onStop中注册/注销监听,避免内存泄漏
修改后的代码示例
VideoExoPlayerActivity 修正版
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_video_exo_player); viewModel = new ViewModelProvider(this, new CommonFactory<>(this)).get(VideoPlayerViewModel.class); // 异步初始化CastContext,替换同步getResult() CastContext.getSharedInstance(this, localExecutor) .addCallback(new FutureCallback<CastContext>() { @Override public void onSuccess(@Nullable CastContext result) { mCastContext = result; // 在这里执行Cast相关组件初始化 initCastComponents(); } @Override public void onFailure(Throwable t) { Log.e("CastInit", "CastContext初始化失败", t); } }, localExecutor); initView(); hideStatusBar(); startService(new Intent(this, HistoryAPIBackgroundService.class)); } // 封装Cast组件初始化逻辑 private void initCastComponents() { if (mCastContext == null) return; mSessionManager = mCastContext.getSessionManager(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); // 初始化MediaRouteButton等组件 mMediaRouteButton = binding.mediaRouteButton; MediaRouteHelper.setMediaRouteButton(mMediaRouteButton, mCastContext); } // 生命周期中注销监听,避免内存泄漏 @Override protected void onStop() { super.onStop(); if (mSessionManager != null) { mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); } }
VideoBrowserActivity 修正版
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.video_browser); setupActionBar(); mCastStateListener = new CastStateListener() { @Override public void onCastStateChanged(int newState) { if (newState != CastState.NO_DEVICES_AVAILABLE) { showIntroductoryOverlay(); } } }; // 异步初始化CastContext CastContext.getSharedInstance(this, localExecutor) .addCallback(new FutureCallback<CastContext>() { @Override public void onSuccess(@Nullable CastContext result) { mCastContext = result; mCastContext.addCastStateListener(mCastStateListener); initCastComponents(); } @Override public void onFailure(Throwable t) { Log.e("CastInit", "CastContext初始化失败", t); } }, localExecutor); } private void initCastComponents() { if (mCastContext == null) return; mSessionManager = mCastContext.getSessionManager(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); // 初始化MediaRouteMenuItem if (mediaRouteMenuItem != null) { MediaRouteHelper.setMediaRouteButton((MediaRouteButton) mediaRouteMenuItem.getActionView(), mCastContext); } } @Override protected void onStop() { super.onStop(); if (mCastContext != null) { mCastContext.removeCastStateListener(mCastStateListener); } if (mSessionManager != null) { mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); } }
额外检查项
- 确认项目已正确引入Google Cast依赖:
com.google.android.gms:play-services-cast-framework - 检查AndroidManifest.xml中是否配置了Cast相关meta-data,比如:
<meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" android:value="com.yourpackage.CastOptionsProvider" /> - 避免在主线程执行耗时操作,保持UI线程流畅
内容的提问来源于stack exchange,提问作者CDK
相关产品推荐
相关产品推荐

