You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:31:44