views:

44

answers:

2

I have an extended dialog class that I want to show for 3 seconds then disappear. This works great the first 2 times it's called, but then it crashes my app after that. Admittedly, I'm not the best with threads and I think that's where my problem might be. As you can see from the code below (commented out section), I tried using a cancel event to kill the thread that is spawned, but that makes it crash the first time it's run. I've also tried doing all of this on the parent class' UI thread which yields the same result as this (crashes after 3 times displaying the dialog).

import java.util.Timer;
import java.util.TimerTask;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;


public class HandResults extends Dialog implements DialogInterface {

    HandResults hr;
    Timer myTimer;
    Handler hand = new Handler();
    Thread t;

    public HandResults(Context context) {
        super(context);
        setContentView(R.layout.handresults);
        hr = this;
        /*
        this.setOnCancelListener(new OnCancelListener(){
            public void onCancel(DialogInterface dialog) {
                t.destroy();

            }
        });
        */
    }

    public void showHands(){
        this.show();
        myTimer = null;
        myTimer = new Timer();
        myTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                TimerMethod();
            }

        }, 3000);
    }

    private void TimerMethod()
    {
        t = new Thread(){
            public void run(){
                   hand.post(Timer_Tick);       
            }
        };
        t.start();
    }

    private Runnable Timer_Tick = new Runnable() {
        public void run() {
            hr.cancel();
        }
    };
}
A: 
  1. When the onCancel event is received you're calling t.destroy() and destroy is a deprecated method.
  2. You don't need to start another thread if you're creating a timer, which already runs asynchronously.

So this might work better:

public class HandResults extends Dialog implements DialogInterface {

    HandResults hr;
    Timer myTimer;
    Handler hand = new Handler();

    public HandResults(Context context) {
        super(context);
        setContentView(R.layout.handresults);
        hr = this;
    }

    public void showHands(){
        this.show();
        myTimer = null;
        myTimer = new Timer();
        myTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                hr.cancel(); // call the cancel method directly
            }

        }, 3000);
    }
}

There is no need to create your own thread, so the above code should do approximately what you're trying to do.

Lirik
I had the thread stuff commented out, I just included it in my code to show that I tried it. In any case, your code does the same thing mine was doing before, it works 2 times, then the application force closes. I have now tried this with like 3 other methods (handler.postDelayed, passing a runnable and handler from the calling method etc), and everyone has the same result...it works twice then fails. Any other ideas?
Kyle
turns out that there is something else causing it to force close (in conjunction with this). I'm displaying this based on results that get streamed in from a socket and I'm guessing that the thread from the socket class I wrote is conflicting here...I'm not sure, but when I took that out of the equation, your code works fine. So I guess I need to go back to the drawing board and figure out another way to call the showHands() method :/ Thanks for your help.
Kyle
@Kyle, what's the exception that you're getting?
Lirik
I'm not sure. It just force closes the application. Is there a way I can log the exception somewhere? (I realize that's a very newb question, and I apologize in advance for even asking). I haven't been able to do any exception troubleshooting once the app is running on my phone or the emulator (using eclipse). Knowing this would actually have saved me a lot of time but I've been too embarrassed until now to ask :). Since this one is driving me nuts, I figured it's time to swallow my pride and figure it out.
Kyle
yay I found the culprit and got it working great. would still like to know how to trap and view exceptions from the emulator though. thanks again for all your help Lirik.
Kyle
Look in the logcat
Falmarri
A: 

You don't need the treat t here, you can run hand.post() inside the TimerTask. And even the TimerTask/Timer is not needed, you can use handler.postDelayed(). I don't know where the behaviour you observe comes from, though. Also, you should consider that your Dialog is closed early (e.g. when the use rotates the screen). You can call handler.removeCallbacks() in that case.

devisnik