0

There will be a lot of code. I had to leave it for you to understand logic of an application. Here is the MainActivity. Called on starting.

public class MainActivity extends AppCompatActivity {

    private GameView gameView;

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

    public void startSurvival(View view) {
        gameView = new GameView(this, this, "survival");
        setContentView(gameView);
    }

    public void chooseData(View view){
        setContentView(new DView(this, this));
    }

    public void backToMenu(){
        setContentView(R.layout.activity_main);
        gameView = null;
    }

    @Override
    protected void onResume() {
        super.onResume();
        try {
            gameView.update();
        } catch (NullPointerException e) {}
    }
}

This Activity is a List of options. You choose one and then GameView sets as content View with appropriate parameters. Here is no questions so I cut almost all the code.

public class DView extends ListView {

    DView(final Context context, final MainActivity mainActivity){
        super(context);

        this.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String[] columns = {"data"};
                String having = "id = " + ids[position];

                SQLiteDatabase db = dbHelper.getWritableDatabase();
                Cursor cursor = db.query("levels", columns, null, null, ID, having, null);

                if (cursor.moveToFirst()){
                    int dataInd = cursor.getColumnIndex(DATA);
                    mainActivity.setContentView(new GameView(context, mainActivity, cursor.getString(dataInd)));
                }//everything here works fine. This just shows that setContentView can be done multiple times 
        //without bugs 
                cursor.close();
                dbHelper.close();

            }
        });
    }
}

And here comes the problem. When win() method is called display turns black. Application does not crash.

public class GameView extends SurfaceView{

    public MainActivity mainActivity;
    GameThread gameThread;
    public Player player = null;
    public Canvas canvas;
    public ExtraData data;

    public GameView (Context context, MainActivity mainActivity, String data){
        super(context);
        this.mainActivity = mainActivity;
        if (data.equals("survival")) {
            this.data = new ExtraData("RandomSpawn47",null, this);
        } else {
            this.data = new ExtraData("UsingData", data, this);
        }
        update();
    }

    void update(){
        gameThread = new GameThread(this);
        getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                gameThread.running(true);
                if (gameThread.getState() == Thread.State.NEW)
                    gameThread.start();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                gameThread.running(false);
            }
        });
        if (player == null)
            player = new Player(this);
    }

    public class GameThread extends Thread{
        private GameView gameView;

        public GameThread(GameView gameView) {
            this.gameView = gameView;
        }
            public void running(boolean run){
                running = run;
        }

        @Override
        public void run() {
            while (running){
                 canvas = null;
                try{
                    canvas = gameView.getHolder().lockCanvas(null);
                    synchronized (gameView.getHolder()){
                        draw(canvas);
                        this.wait(45);
                    }
                } catch(Exception e) {}
                finally {
                    if((canvas != null)&&(running)){
                        gameView.getHolder().unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
    }
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawColor(Color.BLUE);
        data.onDraw();
    }

    public void win(){
        mainActivity.backToMenu();//not switching the menu
    }
}

Other classes like ExtraData and Player are not important.

GameThread and SurfaceView destroyes (I checked them with Logs in onDestroy() and in the end of run() method).

Zoe
  • 27,060
  • 21
  • 118
  • 148
  • I believe this should help in removing views. https://stackoverflow.com/a/7295641/6142219 – Deepak kaku May 04 '18 at 17:19
  • I don't think removing views is actually the problem here as when I set new content view with the DView as a content view everything works fine. –  May 04 '18 at 21:24
  • that's what I am trying to say. new view gets initialized but it is not removed. Its like a blank slate from which you removed only the paper, but you need to remove the whole blackboard out – Deepak kaku May 04 '18 at 21:45
  • I still don't get it. Why then with DView all went smoothy? And the method shown in the link is used to remove a child object from it's parent. –  May 04 '18 at 22:46
  • maybe you need to re-instantiate main view like you did for Dview. My guess is till with removing the views. but I just read setContentView replaces exisitng view. – Deepak kaku May 04 '18 at 23:14

1 Answers1

0

You are calling method of Activity from another class. Instead of mainActivity.backToMenu(), create one interface, implement it in MainActivity and pass the reference in GameView to initialize the interface. And where you are calling win method, call interface method instead of calling the public method of MainActivity.

Create one interface like:

public interface UpdateActivity{
    void updateActivity();
}

In MainActivity

public class MainActivity extends AppCompatActivity implements UpdateActivity

then override the method of interface

void updateActivity(){
        setContentView(R.layout.activity_main);
        gameView = null;
}

Pass the reference in GameView instead of passing the MainActivity reference.

    public GameView (Context context, UpdateActivity updateActivity , String data) {
        super(context);
        this.updateActivity = updateActivity ;
        if (data.equals("survival")) {
            this.data = new ExtraData("RandomSpawn47",null, this);
        } else {
            this.data = new ExtraData("UsingData", data, this);
        }
        update();
    }

Now call the method where you want to call:

updateActivity.updateActivity();
Däñish Shärmà
  • 2,891
  • 2
  • 25
  • 43