In my android app, there is a SurfaceView. Whenever user touches it a short( 1 sec) animation is rendered on the SurfaceView by a AsyncTask. I face force close problem in two scenarios.
When used presses Back key while the animation is running.
In the arcade mode game duration is of 60 seconds. At the end of game, new activity is started. If at the end of the game , the animation is still running while the new activity is started, I get force close error message.
How can I check if the AsyncTask is complete i.e. the animation is over, before Back key press takes effect or new activity is started ? Using AsyncTask.getStatus() in a while loop is freezing the app. Or is there any alternative way to do this?
One of the way to wait for it to finish is like asyncTask.execute().get() ;
with this your main thread will wait this to finish
Related
So I have two fragment alternatively replacing each other (both containing a countdowntimer), until the end of a game. I'd like to implement a pause button, who, like his name indicates, would pause the fragment underneath.
I was thinking to do that with a dialog fragment to do that smoothly but if you have another suggestion, I'm open minded.
When clicking on the button, a pause menu will appear and the countdowntimer underneath will stop. When resuming the game, it will continue where it stopped.
Thanks in advance !
As far as I know, CountDownTimer class does not provide a method for pause. The best workaround for this is to save the remaining time when the pause button is clicked, and to create a new CountDownTimer with that amount of time when the game is unpaused.
I've done this in an app I made some time ago, where I needed to manipulate the time by adding or subtracting the time, same idea. Make the new timer, cancel the old one, and start the new one.
In my android game there is an arcade mode which runs for 60 sec. The gamescreen consists of a gameboard, which consists of a 6x6 matrix of coloured circles drawn on a surfaceview. There is a timer and scoreboard to keep track of time and score. Timer is basically a separate thread sleeping for 60 sec and updating a handler attached to UI thread every sec. As soon as time left becomes zero the games goes to another activity where the player's current score and past scores are displayed. If the player presses back key then previous activity (gamescreen) becomes visible, however the scoreboard is not reset but the matrix is redrawn. All the coding is in onCreate() method or new methods created for the game. There is no code in onPause() or onResume() methods. Then why the surfaceview is recreated and redrawn ? I dont think pressing back key runs onCreate() method.
Your first activity will be destroyed if you call explicitly call finish().
Even if you do not, your activity can be destroyed any time after it becomes fully obscured.
So it is wrong to presume onCreate() will not be called.
As my app (game) is getting larger and larger, I've started to encounter a problem.
I have a menu activity with a 'start game' button - when the user presses this button, it starts the main game activity - now in this activity, I'm creating bitmaps etc in the constructor but there are so many that now when the activity starts, there is a slight delay - about 2 seconds - before the game actually starts.
I'm clearly doing something wrong - please could someone advise how to get around this so the delay (which clearly, has to happen) - isn't noticed by the user.
Load the ones you need immediately right away. Load the rest on a background thread (probably an AsyncTask). If you need one before it may be loaded, either pause or put up a loading screen as needed.
You could start loading the bitmaps in the background of your menu activity, or even when your app is created using a background thread or AsyncTask. You'll still need a loading screen of some sort in case the user navigates to the main game activity before you're done loading all of the bitmaps though.
You can also kick off an IntentService to load the bitmap. When the bitmap is loaded the IntentService can send a broadcast using LocalBroadcastManager. Then each component that cares about a result can register a BroadcastReceiver with LocalBroadcastManager.
On cocos2d-x's game. When I pressed the home button to quit the game. The next time, how can I make the game must start over again, but not followed by the last exit scene
Ideally in applicationWillEnterForeground you should simply replace the scene with a new instance of it to start over e.g. if the class of scene you were running is called GameLevelScene you should simply tell CCDirector to replace the running scene with a new instance from it's class. For example:
CCDirector::sharedDirector()->replaceScene(GameLevelScene::create());
But while I was doing something similar to pause my game on resuming from background I noticed that it wasn't quite working (it should've, maybe this is some problem with cocos2d-x). So, as a work around, I created a sequence with a delay time of zero at it's start and then called my game's pause function. I guess the game needed to take one tick to process this after resuming from background. For you, if the above doesn't work just try this:
someNode->runAction(
CCSequence::create(CCDelayTime::create(0.0f),
CCCallFuncO::create(CCDirector::sharedDirector(),
callfuncO_selector(CCDirector::replaceScene),
GameLevelScene::create()),
NULL));
someNode can be any node in your game which is living in the game i.e. it hasn't been destroyed; it must be an alive object. You can have a game manager node which is alive at all times during your game. The game manager node can be made responsible for such game management issues.
The first activity of my application is a splash screen, where some animation is displayed while some loading occurs in a background thread using AsyncTask.
Once the loading in the background is done, I want to start a new activity. What is the correct way to do that ?
Start a new activity directly from the onPostExecute method of the AsyncTask class.
Check if the current activity is displayed before starting the new activity :
If the current activity is display, start the new activity.
If the current activity is NOT display, use a flag (boolean) and check the flag during the onResume method in order to start the new activity there.
My main concern is :
If my application went to the background (due to an incoming phone call, a home key press, ...) and the background thread (AsyncTask) finished executing, and a new activity is started from the onPostExecute method while my application is still in the background : What happens ?
Will the new activity start directly as soon as my application is visible again ?
I faced a similar situation: my application went to background and after some time the app started an intent displaying another activity. However, the app's behavior now depends on the os that it's running:
on pre 4.4 devices the app silently opens the new activity and remains in background. When the user resumes the application, he is prompted with the second activity already.
on 4.4 devices (tested on 4.4.2 and 4.4.4) the app opens the second activity, but after 3-4 seconds, the app pops to foreground, interrumping the user.
Hope it helps anybody. I'm still looking solutions for the second case in order to prevent the app from popping to foreground.
From my experience i am answering your question
Question1
If you using AsyncTask you have to start new activity in OnPostExecute(). In my experience this is the correct way of doing it.
Question2
When ever your press the home key or receiving phone call. Your activity will go in to background until you exit the app by pressing back button(at that time your app is exited). So when you come back to your app your new activity will be visible if background process get finished. Otherwise you will see the start splash screen.
I think that it is dependent upon the OS of android. It has defined some built in priority model for each of the components.
Look at the answer given by commonsware.
change process priority in android
this gives brief idea about components priority.