3秒后取消对话 - 在多次使用后不断崩溃我的应用程序

时间:2010-08-21 18:37:06

标签: android multithreading dialog timer

我有一个扩展的对话框类,我要显示3秒然后消失。它的前两次调用效果很好,但之后它会崩溃我的应用程序。不可否认,我不是最好的线程,我认为这是我的问题所在。正如您从下面的代码(注释掉的部分)中看到的那样,我尝试使用取消事件来终止生成的线程,但这会使它在第一次运行时崩溃。我也尝试在父类的UI线程上完成所有这些,产生与此相同的结果(在显示对话框3次后崩溃)。

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();
        }
    };
}

2 个答案:

答案 0 :(得分:4)

  1. 收到onCancel事件后,您正在调用t.destroy(),而destroy是不推荐使用的方法。
  2. 如果您正在创建一个已经异步运行的计时器,则无需启动另一个线程。
  3. 所以这可能会更好:

    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);
        }
    }
    

    没有必要创建自己的线程,因此上面的代码应该大致完成您要做的事情。

答案 1 :(得分:0)

这里不需要处理,你可以在TimerTask中运行hand.post()。即使不需要TimerTask / Timer,也可以使用handler.postDelayed()。 但我不知道你观察到的行为来自哪里。 此外,您应该考虑提前关闭对话框(例如,当用户旋转屏幕时)。在这种情况下,您可以调用handler.removeCallbacks()。