0

I decided to try and make my code more object oriented and avoid repetitive code in another class.

Source code for Activities :

     public class EasyMode extends MainActivity {

            GameActivityPVP game = new GameActivityPVP();

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

                game.initializeButtons();
            }
        }


    public class GameActivityPVP extends MainActivity {

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

            initializeButtons();
        }

        public void initializeButtons() {

            button[0] = (Button) findViewById(R.id.button1);
        }
}

The second the program gets to the line where I try to call a method using game.methodName(); the program crashes. No compiling errors or anything. I am new to programming in general so please take it easy on me and I tried to simplify my code as much as possible.

Android Monitor/logcat :

W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...

and

W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
Chris
  • 81
  • 10
  • 2
    long story short, `Activities` has lifecycle controlled by android OS which you can't do it using `new` – Pavneet_Singh Dec 12 '17 at 06:59
  • @Pavneet_Singh Is there a short solution as well? – Chris Dec 12 '17 at 07:01
  • what is your intention? what actually you are trying to achieve , you have to give more info about your intention and code – Pavneet_Singh Dec 12 '17 at 07:05
  • @Pavneet_Singh My intention is to avoid writing the same exact method twice in another class. Its a game of tic tac toe. The easy mode class uses a random # generator as an "AI". the GameActivityPVP is player vs player. In the GameActivityPVP class i have a method so when there is a tie or winner or full board i reset the board. instead of rewriting this method in the easy mode class i thought i would be able to do it this way, i also wanted to do this with initializing the 9 buttons for the board. – Chris Dec 12 '17 at 07:12
  • You cannot do that, Lemme tell you why? Because these are two different Activities. Do one thing.. Make on class separate name it Utils. do not EXTEND it. make it constructor. and make one method. and use that Utils' method in every class whereever needed. – Abhishek Charismatic Dec 12 '17 at 07:15
  • @AbhishekCharismatic Sounds promising, would not have thought of that. thank you – Chris Dec 12 '17 at 07:17
  • @Chris I have updated my answer.. check – Abhishek Charismatic Dec 12 '17 at 07:20
  • @Chris did you managed to fix the problem? – Iulian Popescu Dec 13 '17 at 09:25

3 Answers3

2

You can use another class's method by creating object of parent class.

See below example;

Here you want to use method from 'GameActivityPVP' class. So you need to create one object in this class only.

  public class GameActivityPVP extends MainActivity {

        public static GameActivityPVP mGameActivity;

        public GameActivityPVP getInstance(){
             return mGameActivity; // assign value in onCreate() method.
        }

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

                mGameActivity = this; // Do not forget this, otherwise you'll get Exception here.
                initializeButtons();
            }

            public void initializeButtons() {

                button[0] = (Button) findViewById(R.id.button1);
            }
    }

Now use this Object in another class 'EasyMode' like this;

if(GameActivityPVP.getInstance()!=null){
    GameActivityPVP.getInstance().initializeButtons();
}
Bhoomika Patel
  • 1,895
  • 1
  • 13
  • 30
0

Try This:

Make one Class Utils:

In Utils:

public class Utils{
private Activity context;
Button button;
public Utils(Activity context) {
    this.context=context;

}

public void inititializeButton(Activity context){
    button[0]= (Button) context.findViewById(R.id.button_flasher);
}

}

And in your Class use:

 public class EasyMode extends MainActivity {

        Utils utils;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.game_layout_pvp);
            utils=new Utils(this);
            utils.initializeButtons();
        }
    }
0

As already stated, you shouldn't use nested activities, they are not supposed to interact like this. If you want two activities to interact you have to do it through an intent. Regarding the duplicated code, you have few solution presented but my personal opinion is that the OOP rules are not followed. If I had to write that logic, I would create a BaseActivity to hold the common logic of the other two activities and use inheritance to extend them.

public class BaseActivity extends Activity {
    protected List<Button> buttons = new ArrayList<>();

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

        initializeButtons();
    }

    protected void initializeButtons() {

        buttons.add((Button) findViewById(R.id.button1));
    }
}

public class EasyMode extends BaseActivity {
    // Add here logic that is used only in EasyMode activity
}

public class GameActivityPVP extends BaseActivity {
    // Add here logic that is used only in GameActivityPVP activity
}

Note that in this way you don't have to override onCreate again to initialise the buttons and so on. Also, I saw that you used the same layout for both activities, but if you want to use different layouts you can do it as usual and then call initializeButtons.

Iulian Popescu
  • 2,595
  • 4
  • 23
  • 31