How Can I Fix Error Using Intent for a Game Over Screen in Android

When I first started building my Android game using Java, I had a simple goal, I wanted the game to transition to a Game Over screen when a countdown timer hit zero.

Instead of a clean transition, I got slapped with an error that simply said:

expression expected

It wasn’t very helpful, and it took me longer than I’d like to admit to figure out what was wrong. So if you’re in the same boat, let me walk you through what went wrong, why, and how I fixed it with some added improvements along the way.

The Problem

Here’s what I was trying to do in my GameView class:

((GameActivity).getContext()).goSplash();

This was supposed to trigger an Intent and take me to the GameOverScreen when the timer hit zero. But it wouldn’t even compile. The error expression expected kept popping up, and I had no idea what that meant at first.

The Root Cause

After a bit of debugging, I realized there were two main issues in my original approach.

Syntax Error

Here’s the broken line again:

((GameActivity).getContext()).goSplash();

This is not valid Java syntax. I was trying to cast getContext() to GameActivity, but I placed the parentheses incorrectly. The corrected version is:

((GameActivity) getContext()).goSplash();

Now, getContext() is being cast to GameActivity, and Java is happy with that.

Bad Design Calling Activity Method

Even with the fixed syntax, this line still felt wrong. Calling an Activity method directly from a View using getContext() is very tightly coupled, and not something I’d recommend for a scalable app. It can cause issues if the context isn’t exactly what you expect.

The Fix

I went ahead and refactored the logic for better safety and reliability. Here’s what I ended up with:

GameView.java

long timeNow = System.currentTimeMillis();
long timeLeft = 10 - (timeNow - startTime) / 1000;

if (timeLeft >= 0) {
canvas.drawText(Long.toString(timeLeft), 20, 30, text);

if (timeLeft == 0) {
Context context = getContext();
if (context instanceof GameActivity) {
((GameActivity) context).goSplash();
}
}
}

This time, I’m checking if the context is actually an instance of GameActivity before calling goSplash().

GameActivity.java

public void goSplash() {
Intent intent = new Intent(this, GameOverScreen.class);
startActivity(intent);
finish(); // Optional: close GameActivity so the user can't return
}

When the timer reaches zero, the game navigates to the Game Over screen as intended.

Extra Functionalitie for Practice

Once I had the basic functionality working, I decided to add a few improvements to make the code more reliable and maintainable.

Prevent Multiple Intent

Sometimes, the timer check fires multiple times leading to multiple Intent calls. That’s bad.

So I added a simple flag:

private boolean isGameOver = false;

...

if (timeLeft == 0 && !isGameOver) {
isGameOver = true;
((GameActivity) context).goSplash();
}

Just declare isGameOver as a class-level variable in GameView, and you’re good.

Use a Listener Instead of Direct Activity Call

Directly calling activity methods from a view breaks separation of concerns. A better solution? Use an interface.

In GameView.java

public interface GameOverListener {
void onGameOver();
}

private GameOverListener listener;

public void setGameOverListener(GameOverListener listener) {
this.listener = listener;
}

...

if (timeLeft == 0 && listener != null) {
listener.onGameOver();
}

GameActivity.java

gameView.setGameOverListener(() -> {
goSplash();
});

Now GameView doesn’t even need to know what Activity it’s in. Much cleaner.

Summary

ProblemSolution
Syntax error in castingUse ((GameActivity) getContext()).goSplash();
Tightly coupled codePrefer interface callbacks
Repeated Intent callsAdd isGameOver flag

Final Thought

This error was frustrating at first, but it turned out to be a great opportunity to learn better architecture patterns in Android. If you’re ever tempted to call an Activity method from a View, take a moment and ask.

Using interfaces, safety checks, and separation of concerns made my game code more maintainable and scalable and I can now reuse GameView in other parts of the app without it crashing or misbehaving.

Related blog posts