我已经为此工作了好几个星期,不是开玩笑,但我真的对这一部分感到困惑。因此,我正在将 Google Cast 实现到我继承的一个构造不良的代码库中。
具体来说,我使用此源作为参考,因为代码库出于某种任意原因完全用 Java 编写:https://github.com/googlecast/CastVideos-android
更具体地说,我现在要做的就是得到
mCastContext = CastContext.getSharedInstance(this,localExecutor).getResult();
VideoBrowserActivity 中的 line 可以在我的项目中工作。但是,我在实现它时收到此错误,但在运行其他项目时却没有收到此错误:无法启动活动 ComponentInfo{}: java.lang.IllegalStateException: 任务尚未完成
以下分别是我工作的重要部分和参考文件:
public class VideoExoPlayerActivity extends BaseActivity implements OnClickHandlerInterface {
private ActivityVideoExoPlayerBinding binding;
private VideoPlayerViewModel viewModel;
private String videoUuid;
private ExoPlayer exoPlayer;
private DefaultTrackSelector trackSelector;
private String drmLicenseUrl;
private String mimeType;
private Boolean isDashDRM;
private AudioManager manager;
private boolean isScreenLock = false;
private boolean isShortVideo = false;
private boolean isRollOverVideoAvailable = false;
private boolean isRollOverShow = false;
private boolean isRollOverDismiss = false;
private int currentPosition = 0;
private int continuePosition = -1;
private List<VideoUuidURLModel> list_url = new ArrayList<>();
private List<VideoPlayerDataResponse.Data> list_video = new ArrayList<>();
private PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
private CastContext mCastContext;
private CastSession mCastSession;
private MediaRouteButton mMediaRouteButton;
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));
}
public class VideoBrowserActivity extends AppCompatActivity {
private static final String TAG = "VideoBrowserActivity";
private CastContext mCastContext;
private final SessionManagerListener<CastSession> mSessionManagerListener =
new MySessionManagerListener();
private CastSession mCastSession;
private MenuItem mediaRouteMenuItem;
private MenuItem mQueueMenuItem;
private Toolbar mToolbar;
private IntroductoryOverlay mIntroductoryOverlay;
private CastStateListener mCastStateListener;
private Executor localExecutor = Executors.newSingleThreadExecutor();
private class MySessionManagerListener implements SessionManagerListener<CastSession> {
@Override
public void onSessionEnded(CastSession session, int error) {
if (session == mCastSession) {
mCastSession = null;
}
invalidateOptionsMenu();
}
@Override
public void onSessionResumed(CastSession session, boolean wasSuspended) {
mCastSession = session;
invalidateOptionsMenu();
}
@Override
public void onSessionStarted(CastSession session, String sessionId) {
mCastSession = session;
invalidateOptionsMenu();
}
@Override
public void onSessionStarting(CastSession session) {
}
@Override
public void onSessionStartFailed(CastSession session, int error) {
}
@Override
public void onSessionEnding(CastSession session) {
}
@Override
public void onSessionResuming(CastSession session, String sessionId) {
}
@Override
public void onSessionResumeFailed(CastSession session, int error) {
}
@Override
public void onSessionSuspended(CastSession session, int reason) {
}
}
/*
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
@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();
}
我的有些东西看起来缺失了,但我已经尝试实现你已经看到的所有内容,并且没有任何东西改变我的结果。请询问您是否需要查看代码的其他部分,因为我不知道这个问题是否来自其他地方。据我所知,几乎没有关于在 Java 中实现这一点的教程,所以我非常盲目地做这件事,而且非常困难,所以我真的很感谢我能得到的任何帮助。
这并不能直接回答您的问题,即为什么您的应用程序的行为与 Google Cast 参考应用程序不同,但您可以添加 OnCompleteListener 然后设置上下文:
科特林:
CastContext.getSharedInstance(this, castExecutor).addOnCompleteListener {
castContext = it.result
castContext?.addCastStateListener(this)
}
Java:
Task task = CastContext.getSharedInstance(this,localExecutor);
task.addOnCompleteListener(task1 -> mCastContext = (CastContext) task1.getResult());
// or
Task task = CastContext.getSharedInstance(this,localExecutor);
task.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
mCastContext = (CastContext)task.getResult();
}
});
我陷入了同样的境地(今天的大部分时间),就像你自己试图弄清楚为什么 CastContext.getSharedInstance(this,castExecutor).result 在我自己的应用程序中给出“任务尚未完成”异常,但在参考应用程序中却没有尽管据我所知我已经遵循了相同的步骤。
我猜这不是最好的选择,但如果你想在主线程中获取对象,这对我有用。我在 Kotlin 的 daggerHilt 中附加了 mi 代码:
@Singleton
@Provides
fun provideCastContext(context: Context) : CastContext {
val executor = Executors.newSingleThreadExecutor()
val castContextTask: Task<CastContext> = CastContext.getSharedInstance(context, executor)
return try {
runBlocking {
castContextTask.await()
}
} catch (e : Exception) {
throw IllegalStateException("error couldn't get CastContext")
}
}