How to pause loop to wait for button press - android

I'm trying to create a turn based game using a 1v1 battle for android. My basic game loop checks if the two fighters are dead, if not then checks who is to go next. If its the player's turn then it should wait for an attack button to be clicked. If its the computer's turn, then it will execute a random attack. I'm having trouble getting the program to wait for the user input. I tried setting the button listener here but that's not doing it.
[edit] The determination for which character goes is based on a recovery integer. Each attack has a recovery value (50-100) which is added to the character's recovery. The nextMove() method checks to see which is closer to 0 and subtracts the difference from both characters. This allows the game to require more strategy because you don't attack just once a turn.
What can I do to get the game to pause at that point
Here's the code
public void battle(){
boolean playerGo;
while(!checkDead()){
playerGo=nextMove(); //returns true if its the players turn to go
if(playerGo){
//The game should wait here for the user input
moveButton1.setOnClickListener(this);
}
else{
randomMove(); //game automatically goes
}
}
}

When your app starts up, there's one thread on which everything runs, including event handlers. After you do your setup and call battle(), that thread is sitting there going around and around the loop. It's so busy going around and around the loop that it doesn't notice that there's a click event waiting to be processed!
There's a few options:
Restructure your code. It looks like the basic structure is that the player moves, then the game moves. You could remove this loop entirely, and instead call randomMove() after each time you handle the player's move. Handle the player's move in the OnClickListener for moveButton1. That way everything just happens on events. This would be simpler overall, and is probably the Right Thing to do.
Make the smallest possible change to your code to get it working. This would probably mean pulling the contents of your while loop into a Runnable, which you schedule by calling Handler.post. The first line calls checkDead and returns if true. The last line reschedules the Runnable. In between is the body of the while loop. The effect of this is that your loop body runs, then the event handler gets a turn, then your loop body runs, then the event handler runs. This is probably a bad idea.
Run battle() in another thread. This is probably a bad idea.
Why are 2. and 3. bad ideas? On a mobile device, battery life is precious, and running a check to see if you need to do something over and over again will keep the CPU busy chewing up battery life. Much better to sit there idle until you need to do something - this is what option 1 achieves.
So if 2. and 3. are bad ideas, why mention them? Welllllll, 2. I mention because it's the closest thing I've got to an answer to the question you actually asked. I mention 3. because there's a sense in which your current code is a fairly clear embodiment of the game logic. You could rework it so it runs in a separate thread, and instead of nextMove() returning true, nextMove() waits until the player makes a move (this would involve semaphores or mutexes or promises). But this would be an explicitly multi-threaded program, and as such would be difficult to write correctly. I recommend you don't attempt it at this stage in your programming career - the most likely outcome is a program that stops and waits forever, or that corrupts its data structures, in a way that is exceedingly difficult to diagnose.

Button.SetOnClickListener() function will be triggered, only when the user clicks on the button. As such it doesn't wait\block till the user input. This is by design in Android, that you cannot have a blocking window waiting for user input. Instead change your design to display hint saying 'now its user's move'.
User does first move by clicking the button.
SetOnclickListener() will be invoked. Have the user action code inside it.
Towards end of SetOnclickListener() have the computer action code.
With this cycle you can have user move and computer move chained.

Related

In Android, how to temporarily suspend the changes to a view for a period of time?

Based on my design (too complicated to introduce all the details, I will ask using a simplified example in words), I need to suspend the changes (may be called from different places) to a view (say TextView) for a period of time (given parameter). The description of the problem is as follows:
There is a TextView, named messageDisplay, which displays text updates of many types of on-going statuses (the updates can be given from multiple places). messageDisplay will be updated whenever the setText function is called (the new message replaces the old one). Now, I want to make it pause (or hold/lock the display) for some time if the current message belongs to certain types (say contains certain keywords), and it is ok for other messages not getting the chance of being displayed in the mean time. In other words, once the condition is met, messageDisplay is suspended for changes, until certain time elapses. There are other views/activities, so I do not want to pause the whole app, just the messageDisplay.
Is there a simple solution or a set of function calls to achieve the objective? Or must I define a time interval and write my own function to check whenever a setText call is made, whether it will be denied to execute based on the suspension interval?
Thank you for any discussions or comments!

Structure App using Methods/threads

I know this is a fundamental java question, but i am relatively new to java.
How do i structure the code attached (monitoring) within a UI.
What the code does is just log values, and if certain conditions are activated, it does stuff. The loop () method does pretty much everything, but there are a few small things done by the preceding methods.
Let's say in the UI, I have a 'calibrate' button, which if pressed, runs a calibrate method/thread, and a 'monitoring' button which runs a different 'monitoring' method/thread. The problem is, these methods/threads are at the moment defined in their own project as classes. My ideas are along the lines that i need to construct these 2 classes and then call the methods i want from them in response to UI interaction. However, if i call just the method, for example:
if (monitoring button) {
monitoring.method1;
}
this means that i can't do anything in parallel to that, so I need to make what happens in those classes into thread somehow.
Cheers,
Rokky
Take a look at AsyncTask, this will allow you to run logic in a background thread, leaving your activity free to respond to the user.

Android activity manager

I guess, I have a generic logic problem. I want to logout a user after 15 if there is no activity. How do I find any "activity" in android. How should I go about it...
Experts please help...
You'll need to invest a little thought into exactly what your requirements are here, but from what I can tell, you want to keep track of the user interactions and if a time limit expires since the last interaction, perform some action, in your case logging them out of your application.
Firstly, you'll need some place that you can track when the last interaction occured, since you'll want this to be application wide you could use a singleton to hold this, or override the Application class, either way should do.
Next, you'll need to start tracking user interactions. From your activities, you can override the onUserInteraction method, this gets invoked anytime the user interacts with the application such as key event. Each time you hit this method, update your singleton and let it know something has happened, with a timestamp.
Finally, you'll need some kind of looping check to constantly check if anything has happened recently. Theres various was of doing this, you could have a continuous loop that compares current timestamp to the last recorded event, a bit of draft code :
while(true)
{
if (timeLastEventRecorded < (now - 15))
{
//nothing has happened in 15 minutes, so take corrective action
}
}
Presumably you'll already have some code in your application that takes care of logouts, such as when the user clicks "logout", you should just be able to invoke that in the sample above.
Hope this helps
You should have all activities inherit from a parent activity that overrides onUserInteraction(). In that callback you should reset a static app wide timer that will perform your logout code when the time reaches the end.

ViewFlipper, onClick events not delivered

I have my own implementation of the ViewFlipper (that exactly mocks the Android code, I wrote it before I realized this), the only difference being the fact that I hardcoded an inAnimation and an outAnimation in mine.
One side of the ViewFlipper has a 'flip' button which flips. The other side has a 'save' and 'cancel' button which flips it back. The 'save' performs a DB operation.
When the save or cancel, it flips the card correctly. If I perform the following operation: flip->cancel->flip->cancel..., it works fine. But when I perform: flip->save->flip, the last flip is non-response and logcat shows me that the touch operation was not delivered because of a timeout. The first thing I checked and ensured was that the database operation was not holding off the UI thread, and it was not!
I use the content of the ViewFlipper (using the View.getContent()) to perform DB operations, throw Toasts, build Alert Dialogs and the like. Might this create issues?
I've read a post somewhere saying that there was an issue with the ViewFlipper with animations and onClick() events not being delivered (the discussion ended with no solution). Am I a victim of this?
Try doing the save operation in a thread even though you are sure its not blocking the UI thread.
If that does not work, then set onTouch listener to the save view.

Same Activity called twice... Issue with Multiple AsyncTasks?

I have three simultaneous instances of an AsyncTask for download three files. When two particular ones finish, at the end of onPostExecute() I check a flag set by each, and if both are true, I call startActivity() for the next Activity.
I am currently seeing the activity called twice, or something that resembles this type of behavior. Since the screen does that 'swipe left' kind of transition to the next activity, it sometimes does it twice (and when I hit back, it goes back to the same activity). It's obvious two versions of the activity that SHOULD only get called once are being put on the Activity stack.
Could this be from both onPostExecute()s executing simultaneously and both checking the flags each other set at the exact same time? This seems extremely unlikely since two processes would have to be running line-by-line in parallel...
*****EDIT*** A lot removed from this question since I was way off in what I thought was wrong. Nonetheless I found the answer here quite useful, so I have edited the question to reflect the useful parts.
The only way I can find that this is
possible is if both AsyncTasks'
onPostExecute() executed SO
simultaneously that they were
virtually running the same lines at
the same time, since I set the
'itemXdownloaded' flag to true right
before I check for both and call
startActivity().
Since they are both called on the main application thread, that's not possible, unless you're doing something really strange.
I would introduce some Log calls to ensure that you are not misreading the symptoms.
Beyond that, it is difficult to see any problems from your pseudocode, unless there's a possibility of other downloadID values beyond the three shown. For example, if there is a DL4, and DL4 completed after DL1 and DL2, DL4 would trigger your activity.

Categories

Resources