1

I'm writing a game that players take turns in. At the end of a turn, I send my data to the server and update my database to let me know that it is now the other player's turn. The problem is, what if someone were to kill the app mid-turn? I'm talking going to Task Manager and actually kill it.

I read that onDestory is not always called, so that's a no go. I was then thinking onStop, but onStop is called in other places too. So how can I be sure that the app is actually getting killed and they aren't just like putting the app in the background for example?

Edit: I should also mention this is in a Fragment that I'm checking this, but don't think that'd make a difference.

user1513171
  • 1,912
  • 6
  • 32
  • 54
  • onDestroy should work, why are you saying that it doesn´t works sometimes? – Guillermo Merino Mar 25 '14 at 23:29
  • if the user kills the app mid-turn (thats a wtf in its own right), then why would you need to update anything? it should still be that users turn when they re-open the app – panini Mar 25 '14 at 23:29
  • I read in numerous posts like here: http://stackoverflow.com/questions/18361719/android-activity-ondestroy-is-not-always-called-and-if-called-only-part-of-the That it may not always be called. As for panini's comment. Well in my game, quitting out could be a way to exploit the game. My rounds are timed and basically the user could be like "ok, this didn't work, I'm going to get a fresh 30 seconds by killing the app until I figure it out". – user1513171 Mar 25 '14 at 23:34
  • 1
    @user1513171 in that case, wouldn't you want something in onPause() instead? Or will time still tick down when the app is in the background? – panini Mar 25 '14 at 23:37
  • Well onPause is an option, but onPause is also called when the user just sends the app to the background, no? – user1513171 Mar 25 '14 at 23:40
  • Just wondering.. what happens in your game if the user gets a call mid-turn? Is he going to be penalized for that too? – Bob Mar 25 '14 at 23:48
  • Bob, well as long as the app is not actually killed the player can go back to it. So if they got a call and at the same time Android decided it needed more memory and killed the app, then yes unfortunately that player would lose his turn. I would like to think that is a rare case though. – user1513171 Mar 25 '14 at 23:53
  • I've been thinking this through some more, and I'm just not feeling the sense of trust I need in any of these methods (onPause, onStop, onDestroy) to use one of them. I think what I'm going to do instead is every time a user starts a round, I'll set a property in the database saying they are currently in the game. Then every time the app starts up I'll check to see if there are any games in which it's that players turn and the "currentlyInGame" property is true in the database at which point I'll mark that player's turn being over and say it's the next player's turn. Thanks for the input every – user1513171 Mar 25 '14 at 23:52

3 Answers3

0

I am not sure if this will help you solve the problem completely, but if you want to use onStop() instead of onDestroy(), there is a way to distinguish between a call to onStop() because the activity is dying and a call to onStop() because it's just going to the background:

 if (this.isFinishing ())
 {
  // activity dying
 }
 else
 {
  // activity not dying just stopping
  }

However I do want to point out that although onStop() MIGHT be more reliable that onDestroy(), it's still not guaranteed to be called right away. In my experience onStop() is called eventually, but maybe some time later.

Bob
  • 2,586
  • 7
  • 20
  • 33
  • I'm assuming using getActivity().isFinishing() would be fine too? I'm doing this in a Fragment as it's easier for me to get my information I need to send to the server there. – user1513171 Mar 25 '14 at 23:44
  • Yes, this is a public method so it can be called from anywhere. – Bob Mar 25 '14 at 23:45
  • 1
    This is not a safe answer – Chris Stratton Mar 25 '14 at 23:48
  • 1
    @ChrisStratton - you are right, this is not 100%.. I was pointing out that there is a way to check if onStop() is called as part of activity destruction process or for something else, that's all. – Bob Mar 25 '14 at 23:50
0

In your example, there is no method that gets called. The Linux process hosting your application is killed, interrupting the Java Virtual Machine running your application's code in the middle of whatever it was doing. The application ends without any notice or warning - even finalizers don't run, because there's not really any "cleanup" needed.. the memory is simply reclaimed by the Linux system.

What you should do is design your application architecture so that if one of the players times out (application is killed, network connection is broken, battery dies, phone gets dropped out of a car and ran over by a truck and tossed into a lake), the server is able to detect the timeout and handle the situation accordingly - most likely, end the player's turn for him and move play onward.

tophyr
  • 1,658
  • 14
  • 20
0

You can use the following method. Its called when you swipe the app from the recent list:

@Override
public void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    Log.e("onDetachedFromWindow", "activity dying");
}
Khalid ElSayed
  • 278
  • 1
  • 5
  • 20