Author Topic: Restarting Activity - Garbage Collector doesn't destroy quickly enough  (Read 1893 times)

Offline kbjansen

  • byte
  • *
  • Posts: 37
    • View Profile
Hi there,

i hope you can help me with the following activity-lifecircle problem:

Situation:
I have two Activities, one for the Menu and one for the Game.
The GameActivity is started by the MenuActivity via startActivityForResult(GameIntent) after pressing "start Game"
(see pic0 number 1. )
There are two different jPCT-Environments within these two Activities, that will be individually cleaned by their
associated Activity.onDestroy() method when calling Activity.this.finish().


The user has differnet options after pressing "pause Game":

a. Resume the game
-> simply unpausing the game

b. Quit the game

Code: [Select]
//pseudo code
GameActivity.this.setResult(RESULT_QUIT);
GameActivity.finish();
MenuActivity.onActivityResult(...){ ... case RESULT_QUIT: MenuActivity.finish() }

c. Back to Main Menu
Code: [Select]
//pseudo code
GameActivity.this.setResult(RESULT_MAIN_MENU);
GameActivity.finish();
MenuActivity.onActivityResult(...){ ... case RESULT_MAIN_MENU: MenuActivity.currentScreen = Screen.MAIN_MENU; }

d. Restart the game
Code: [Select]
//pseudo code
GameActivity.this.setResult(RESULT_RESTART);
GameActivity.finish();
MenuActivity.onActivityResult(...){ ... case RESULT_RESTART: startActivityForResult(GameIntent) }


Problem:
When restarting the GameActivity immediately after destroying (see option d.), the jpct-World doesn't load (see pic2),
although the Framebuffer is ready (you can see the key buttons on pic 2).
I think the old GameActivity with the cleaned jPCT-Environment is still on the Activity stack and not
destroyed quickly enough by the garbage collector. (see pic0 number 2. ) [reason for this argument: see clumsy workaround 1, lower]

Restarting the GameActivity by pressing "start Game" after returning to the Main Menu (see option c.) is working (see pic1).

pic0

short workflow


pic1

Display after pressing "start Game"


pic2

Display after pressing "restart Game"

Clumsy workaround 1:
When returning to MenuActivity with RESULT_RESTART, pasting a thread.sleep for 5 sec before calling startActivityForResult(GameIntent)
-> result:  World will be loaded like shown in pic1
Issue:
5 sec blackscreen appears between activity switching

Clumsy workaround 2:
When returning to MenuActivity with RESULT_RESTART, putting a System.exit(0); in GameActivity.onDestroy() as last line
-> result:  World will be loaded like shown in pic1
Issues (EDIT):
-rough Activity changing with short ugly blackscreen, lumberjack style :S
-a following "back to Menu"-action from GameActivity ends up in a restart of the MenuActivity too,
because System.exit(0) clears the states of all Activities! - i guess



Question:
Does anyone know a good way to get rid of old activity instances immediately?
I think about a command like "gc, clean the stack NOW!" (System.gc() doesn't help, still takes 5 sec until the GC get its ash up)

Or is there a way to get the number of the Activities on stack?

I am wondering why no new instance of GameActivity is build after calling startActivityForResult(GameIntent) immediately?
Maybe I have to set a flag like "the old GameActivty is expired"? Any ideas?


EDIT:
Reset the GameIntent before calling startActivityForResult(GameIntent) doesn't help neither









[attachment deleted by admin]
« Last Edit: June 11, 2012, 11:59:34 am by kbjansen »

Offline kbjansen

  • byte
  • *
  • Posts: 37
    • View Profile
EDIT:
If I could remove a single activity from history stack at runtime then the problem would be solved.
Does anyone know a way to do that?

greetings
jan

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Maybe you can manually decouple engine or app related stuff from the stopped Activity. By definition, the garbage collection is supposed to free all available memory before throwing an OOM. If the old Activity is still being referenced, this might not happen soon enough, but if you decouple the actual data from that Activity, it shouldn't matter.

Offline kbjansen

  • byte
  • *
  • Posts: 37
    • View Profile
Within the onDestroy-Method of the Activity, that should be able to get restarted, I call the method destroyAllObjects().
This method resets and 'nulls' all Objects, that were initialized and used by the Activity.

Or what do you mean with decouple?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Yes, i meant something like that...and it doesn't help?

Offline kbjansen

  • byte
  • *
  • Posts: 37
    • View Profile
nope, too bad. I hopped over the log, but have no clue why the Activity is not recreated correctly...
I attach the two logs (one with this issue: log.txt and another with the working workaround: logwithsleep.txt).
Maybe you see something strange...

EDIT:
upps, maybe i should create two new logs, because there were too many objects in this world at that time XD
so unreadable atm ...

EDIT2:
added two new logs...

[attachment deleted by admin]
« Last Edit: June 15, 2012, 10:31:50 pm by kbjansen »