Android Gameloop Thread.join() hangs application - android

Hey all i am implementing the gameloop found here: http://obviam.net/index.php/the-android-game-loop/
My question is why does having:
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
In my surfaceDestroyed() function of my game view hang the application?

thread.join() will BLOCK until the thread you're joining completes. If that thread never completes, that function will never release.

Because thread.join() blocks the calling thread until thread is done.

Related

Android isInterrupted() returns false after interrupting Thread

I have a thread waiting to be notified or to time out
while (!isInterrupted()) {
try {
if (!semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS)) {
Context context = getContext();
// this is where i do my stuff
semaphore.aquire();
}
} catch (InterruptedException ignored) {
ignored.printStackTrace();
}
}
Before i quit my app i call Thread#interrupt() on this thread. Now i debugged the interrupt seemed to be executed fine since the InterruptedException was thrown and the waiting has been canceled.
But for some reason isInterrupted() still returns true after this and the while loop keeps on running.
Why is that?
you can use a boolean in your while loop condition term because when you send the interrupt command, it won't stop the thread and the thread itself decide when to stop itself

How the flow of code in while loop going in android?

I am new in Android (Java) coding . I have a small game program downloaded. In that to terminate the thread , have the code
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.setRunning(false);
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
retry = false;
}
}
Here the code author says if catch the exception , the code will go to try part not to the statement retry = false;
I could not believe that. please advise the flow is correct.
Please advise
Thanks
Anes
The loop will be run once. No matter if an Exception is thrown since retry will always be set to false after the first run. If you wanted the loop to continue until no Exception is thrown, you could place the retry = false; directly after the thread.join(); in the try block so it's only being called when you don't get to the catch block.

Android- Thread.join() causes Application to hang

I have a thread which handles my game loop, when i call .join() on this thread the application stops responding.
I've been trying to fix a problem where the programs never get to the code, I.E the thread never ends.
System.out.println("YAY");
My Thread for the Game Loop:
This thread successfully prints out "Game Ended" but never seems to finish.
Runnable startGameLoop = new Runnable() {//game loop
#Override
public void run() {
AiFactory ai = new AiFactory();
final Button play = (Button) findViewById(R.id.Play);
final Button pass = (Button) findViewById(R.id.Pass);
while(finish==false){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
currentPlayer = game.getPlayer();
if(currentPlayer.isPlayer()==false){
//System.out.println("passCount:" +game.getPasscount());
ai.decide(nextPlay, game.getPreviousPlayed(), currentPlayer, game.getPasscount() );
if(nextPlay.size()!=0){
runOnUiThread(new Runnable(){
public void run(){
changeArrow();
if(nextPlay.size() ==1){
play1Card();
}
else if(nextPlay.size()==2){
play2Card();
}
else if(nextPlay.size()==3){
play3Card();
}
else if(nextPlay.size()==5){
play5Card();
}
}
}
else{
game.addPassCount();
game.nextTurn();
runOnUiThread(new Runnable(){
public void run(){
changeArrow();
}
});
}
}
else if (currentPlayer.isPlayer()==true){
runOnUiThread(new Runnable(){
public void run(){
changeArrow();
play.setClickable(true);
if(game.getPasscount()==3){
pass.setClickable(false);
}
else{
pass.setClickable(true);
}
}
});
}
}
System.out.println("Game Ended");
}
};
Starting and joining the thread to the main thread:
Thread myThread = new Thread(startGameLoop);
myThread.start();
try {
myThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("YAY");
}
To my understanding .join() makes the current thread wait till the new thread has finished before carrying on.
Sorry if this is a stupid question, i'm quite new to threading.
When you call myThread.join() inside Activity.onCreate you block the main UI thread. Of course it looks like your application has stopped responding because the UI thread is the one responsible for redrawing UI. All your calls runOnUiThread never happen because your UI thread is busy waiting on your game loop.
Thread.join makes the current thread wait until the thread you call it on ends. It does not cause the thread you call it on to end. So if that thread is never ending (as you say at the top), calling join will make it hang forever.
If you want to actually end the thread, call cancel on it. But that requires your thread to occasionally call isCanceled() and exit its run function if it returns true.
mythread.join() does not ensure that your "mythread" is ended.
You need to place a notify() in your game loop.
...
...
System.out.println("Game Ended");
synchronized(mythread){
mythread.notify();
}
Basically, when you make a call to wait(), the code waits on the thread's monitor, and a call to notify() causes a thread waiting on the object's monitor to wake up.
Also, you can use notifyAll() to wake up all the waiting threads.
Alternatively, you can use timeout version of wait(), where the thread waits either till it gets notified or it times out.

Android thread sometimes does not start

I must use Thread in an Android project. Sometimes, it works corectly, however sometimes does not; it does not start (does not call SendToServer() method)or it starts but return to another function suddenly (return updated; line)before the thread does not finish.
Note: affected value is bigger than 0, it gives condition and it goes to if statement.
Here is the my code sample;
public static Boolean MyUpdateFunction(MyObject myobject){
Boolean updated=false;
//Code for updating local database
int affected= SqliteDb.update(....);
if(affected>0)
{
//Send updated data to server
//For this I must use Thread(I can't use AsyncThread)
updated=true;
SendToServer();
}
return updated;
}
public static void SendToServer()
{
try{
;
Thread th=new Thread(new Runnable() {
public void run() {
try {
//Create data and send it to server
//.......
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th.start();
th.join();
}
catch(SQLException e)
{
Toast.makeText(myContext,"ERROR: "+e.getMessage(), Toast.LENGTH_LONG).show();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Other people are correct in that an AsyncTask is the way forward, but the direct problem due to what you're experiencing is this (and as such, I would recommend reading up on how Threading works):
When you start the thread, it begins a new process. The UI thread (which is generally where the majority of your code is) continues. So your code will fire the thread with SendToServer(), and then by definition will immediately return updated, as the UI thread immediately goes to the next line.
What you need is a callback from your Thread, which is handled in the onPostExecute() method of an AsyncTask. There's a good tutorial on how to use them and what they do here
Edit:
I've just seen from a comment above that you can't use Asynctasks, fair enough, but you still need a callback/event fired from your Thread to return any results
Instead of using threads and your variables (updated and affected), you can use AsyncTasks: see: http://developer.android.com/reference/android/os/AsyncTask.html
With AsyncTask, you have some methods which are doing exactly what you want:
onPreExecute
doInBackground
onPostExecute
So, what you can do is to check your condition in onPreExecute, then do your SendToServer in the doInBackground and onPostExecute do what you need.

How to stop asynchronous thread after 5 seconds of running

Have to create thread and run it for 5 seconds, then I want to stop. How can I do that?
I can't do anything with time/milliseconds.
THX.
Threading in java is cooperative - you can not forcefully stop a thread. What you can do is signal it to stop (call interrupt() or raise a flag) and then the code willingly stops.
So:
Start running your worker thread. Inside it repeatedly (inside main working loop) check for isInterrupted() AND catch any InterruptedExceptions - exit the thread in this case.
Start a TimerTask to run for 5 sec, then call interrupt() on the worker thread.
Update: poster explained that he already has a working code, he just needs to run it asynchronously without blocking UI.
Solution: setup AsyncTask and run your code inside it's doInBackground() method.
Use the AsyncTask.cancel(true) method.
Sorry for not being clear here. Here is the example I have for synchronous thread.
My function listen() runs for 5 seconds then exits. Listen() is a UDP listener...
Problem I have with this code, it stops my main thread (my phone became unresponsive) until listed() finishes its 5 seconds run. I would like to use asynchronous thread to avoid my phone freezing up. When I said I can't do anything with time, I was trying to say that I can't put some sort of timer in listen() function then measure lapsed time then exit after 5 seconds. Can't do that.
Thread t = new Thread() {
public void run() {
try {
listen();
} catch (IOException e) {
Log.d(TAG, "IOException (Discovery) " + e);
e.printStackTrace();
}
synchronized (this) {
notifyAll();
}
}
};
synchronized (t) {
t.start();
try {
t.join(5000); // 5 sec
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Categories

Resources