-1

I have run into an issue that closes my app upon switching activities. I don't mean for this to be a "fix my code" question, but if it seems that way, let me know what I can do to fix that. I am going to explain what the program does, and what it is supposed to do, and hopefully the good people of StackExchange can help me figure out a fix.

Purpose: The code is supposed to be for a sumple game I designed so that I could become acquainted with android studio (I already know some Java, and wanted to put it to use). The game lands the user on a splash screen (I don't think that code is relevant, but if you wish for me to include it, I will), then once the user taps, they are taken to the "GameActivity" (code below). My code plays a "ready, set, go" intro, then the game begins. The screen changes between green, yellow, and red at random intervals. If the player taps while the screen is green, they earn 1 point. If the screen is yellow, they earn double. Tapping on a red screen will lose them the game. The colors switch at shorter and less predictable intervals over time.

What is actually happening: As soon as I switch activities, I am given an error message. I was able to switch activities and the app functioned properly when I only had the "intro" code, but after adding the rest, the issue has presented itself. In Android Studio, I have no warnings, errors of any kind, or suggestions (on the right side where android studio helps you fix your code). I don't think it is a problem with the manifest or XML because they were working fine at an earlier stage.

package com.nateolson.taptap;

import android.graphics.Color;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

import java.util.concurrent.ThreadLocalRandom;

public class GameActivity extends AppCompatActivity {

    final Handler introHandler = new Handler();
    boolean gameActive = false;

    final View layout = findViewById(R.id.layout);

    //for main method only
    int playerPoints = 0;
    long timeMinMillis = 1000;
    long timeMaxMillis = 3000;
    long randTime;
    long switchReferenceTime = System.currentTimeMillis();
    String colorStage = "green";
    //for main method only

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        final TextView readyMessageView = (TextView) findViewById(R.id.readyTV);

        final TextView getSetMessageView = (TextView) findViewById(R.id.setTV);
        getSetMessageView.setVisibility(View.INVISIBLE);

        final TextView goMessageView = (TextView) findViewById(R.id.goTV);
        goMessageView.setVisibility(View.INVISIBLE);

        layout.setBackgroundColor(Color.RED);
        Runnable switchToYellow = new Runnable() {
            @Override
            public void run() {
                readyMessageView.setVisibility(View.GONE);
                layout.setBackgroundColor(Color.YELLOW);
                getSetMessageView.setVisibility(View.VISIBLE);
            }
        };

        Runnable switchToGreen = new Runnable() {
            @Override
            public void run() {
                getSetMessageView.setVisibility(View.GONE);
                layout.setBackgroundColor(Color.GREEN);
                goMessageView.setVisibility(View.VISIBLE);
            }
        };

        Runnable gameRunnable = new Runnable() {
            public void run() {
                gameActive = true;
            }
        };

        introHandler.postDelayed(switchToYellow, 1500);
        introHandler.postDelayed(switchToGreen, 3000);
        introHandler.postDelayed(gameRunnable, 4500);
        main();
    }



    public void main() {


        while(gameActive) {
            randTime = ThreadLocalRandom.current().nextLong(timeMinMillis, timeMaxMillis);


            if (System.currentTimeMillis() - switchReferenceTime >= randTime) {

                switch (colorStage) {
                    case "green":
                        colorStage = "yellow";
                        break;
                    case "yellow":
                        colorStage = "red";
                        break;
                    case "red":
                        colorStage = "green";
                        break;
                }

                switchReferenceTime = System.currentTimeMillis();
            }


            switch (colorStage) {
                case "green": layout.setBackgroundColor(Color.GREEN);
                case "yellow": layout.setBackgroundColor(Color.YELLOW);
                case "red": layout.setBackgroundColor(Color.RED);
            }

            timeMinMillis -= .03 * timeMinMillis;
            timeMaxMillis -= .02 * timeMaxMillis;

            layout.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    switch (colorStage) {
                        case "green": playerPoints++;
                        case "yellow": playerPoints += 2;
                        case "red":
                            playerPoints = 0;
                            gameActive = false;
                    }

                    return false;
                }
            });
        }

Java for the previous activity (splash screen):

package com.nateolson.taptap;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onSplashPageClick(View view) {
        Intent intent = new Intent(this, GameActivity.class);
        startActivity(intent);
        finish();
    }
}

GameActivity XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout"
    tools:context="com.nateolson.taptap.GameActivity">

    <TextView
        android:id="@+id/readyTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="monospace"
        android:text="Ready?"
        android:textAlignment="center"
        android:textAllCaps="false"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2"
        android:textColor="@android:color/background_light"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/setTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="monospace"
        android:text="Set... "
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2"
        android:textColor="@android:color/background_light"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.502"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/goTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="monospace"
        android:text="GO!"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2"
        android:textColor="@android:color/background_light"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

XML for MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.nateolson.taptap.MainActivity"
    android:gravity="center"
    android:background="#679933"
    android:orientation="vertical"
    android:onClick="onSplashPageClick"
    >
    <ImageView
        android:layout_height="212dp"
        android:layout_width="288dp"
        android:src="@mipmap/splash_screen_logo"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="31dp" />

    <TextView
        android:fontFamily="sans-serif-thin"
        android:textSize="50dp"
        android:textColor="#274D00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="T a p T a p"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_constraintTop_creator="1"
        tools:layout_constraintBottom_creator="1"
        app:layout_constraintHorizontal_bias="0.426"
        app:layout_constraintVertical_bias="0.537" />

</android.support.constraint.ConstraintLayout>

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nateolson.taptap">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".GameActivity"
            android:parentActivityName=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.GAME" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I'm not asking for a handout, and I don't just want someone to fix my code for me. I want to figure out a solution, then learn what I did wrong. I have also tried fixes mentioned in similar posts, to no avail. This is not the same as the "Unfortunately MyApp has stopped" question because I have provided my own code which has not been fixed by any of the solutions suggested in that thread. That question seems very generic and non-specific to any certain scenario as well.

Thank you,

Nate Olson

Nate.Olson
  • 133
  • 1
  • 12
  • What does logcat say? – Adam Forbis Oct 02 '17 at 16:20
  • You need to tell us what the error says and provide error log if possible. – Ilya Gazman Oct 02 '17 at 16:22
  • 1
    Possible duplicate of [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this) – Zoe Oct 02 '17 at 16:25
  • @Ilya_Gazman The logcat comes up with 0 warnings, 0 errors, and the debug was successful. That's all it says. – Nate.Olson Oct 03 '17 at 00:34
  • @LunarWatcher by MCVE do you mean that I need to add the XML code and other Activity's Java? As far as I can tell, it is otherwise minimal and verifiable. (I will begin to add those - including the manifest? - ASAP) – Nate.Olson Oct 03 '17 at 00:35
  • @AdamForbis The logcat comes up with 0 warnings, 0 errors, and the debug was successful. That's all it says. – Nate.Olson Oct 03 '17 at 00:36
  • @LunarWatcher also, I may be misunderstanding what it means to debug. I read through the link that you sent, and it seems like placing print statements in different places would be sufficient. I don't really know what else I could do by way of debugging. Thank you though! :) – Nate.Olson Oct 03 '17 at 02:01
  • You don't need to add all the code; you have to find the minimum code that reproduces an issue. If the layout itself isn't related (for an instance it's "just" inflated) you don't need to add it. As for debug, you have to add some kind of error to the question. Otherwise it's impossible to debug – Zoe Oct 03 '17 at 05:17
  • When you say, switch activities, are you switching to another application? Because I don't see that you have any code to switch them.... – Adam Forbis Oct 03 '17 at 20:12
  • @AdamForbis I just added the rest of the code that may be helpful. Sorry it took a while, I've been a little busy. – Nate.Olson Oct 04 '17 at 23:21

1 Answers1

3
final View layout = findViewById(R.id.layout);

You should not call findViewById outside of a function, and you have to call it after setContentView() is called.

Secondly, you shouldn't do a while(true) on the UI thread. That will block the entire screen, meaning you can't click on anything, and will after a few seconds cause your app to crash. (Search for "App not responding" if you want more information on this).
You should run the while(true) on a background thread. (Though this also causes some issues with the UI, but i'll leave you to figure that out by yourself)

Tim
  • 41,901
  • 18
  • 127
  • 145
Moonbloom
  • 7,738
  • 3
  • 26
  • 38
  • Thank you, this was helpful. A note for anyone else with this same problem - moving the above line into the onCreate() method raised a 'qualifier must be an expression' error, which i solved by creating (in the newly created thread) another View which was the same as above but by a different name, so that I could modify from the UI from within the background thread. Not sure if this is bad etiquette(?), but it solved my issue. Only the intro will play, so that sucks, but my original problem was solved (Thanks!) – Nate.Olson Oct 05 '17 at 01:32