【问题标题】:android: Is your activity running? Dialog box unable to show upon OnFinishandroid:你的活动在运行吗? OnFinish 时无法显示对话框
【发布时间】:2013-11-21 16:38:14
【问题描述】:

我有一个名为SpotOnView 的视图,并且正在扩展Game_shooting_AB。编码如下。

背景:

在 SpotOnView 中有一个倒数计时器。当时间到了,游戏结束,会弹出一个对话框询问用户是想退出还是重新玩。

SpotOn查看代码:

public class SpotOnView extends View 
{
   ......
  // constructs a new SpotOnView
   public SpotOnView(Context context, RelativeLayout parentLayout)
   {
      super(context);          
      resources = context.getResources();            
      layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      ....    

   } 


   public void start_timer() 
   {
        if (!timerHasStarted) 
        {
            countDownTimer.start();
            timerHasStarted = true;
        } 
        else 
        {
            countDownTimer.cancel();
            timerHasStarted = false;
        }
   }

    public class MyCountDownTimer extends CountDownTimer 
    {
        public MyCountDownTimer(long startTime, long interval) 
        {
            super(startTime, interval);
        }

        @Override
        public void onFinish() 
        {
            text.setText("Time's up!");
               ((Game_shooting_AB)getContext()).replay_dialog();  //LINE 181
        }

        @Override
        public void onTick(long millisUntilFinished) 
        {
            ....
        }
    }

Game_shooting_AB 代码:

   public void onCreate(Bundle savedInstanceState) 
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.game_shooting);

      // create a new SpotOnView and add it to the RelativeLayout
      RelativeLayout layout = (RelativeLayout) findViewById(R.id.relativeLayout);
      view = new SpotOnView(this, layout);                                          //EXTENDING HERE
      layout.addView(view, 0); // add view to the layout
    ....
}



public void replay_dialog()    
{
    final Dialog dialog1 = new Dialog(Game_shooting_AB.this, android.R.style.Theme_Translucent_NoTitleBar);
    WindowManager.LayoutParams lp = dialog1.getWindow().getAttributes();
    lp.dimAmount = 0.7f;
    dialog1.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

    Window window = dialog1.getWindow();
    window.setGravity(Gravity.CENTER);

    dialog1.setContentView(R.layout.alert_dialog_replay_shooting);
    dialog1.setCancelable(false);
    dialog1.show();     //LINE 431
    ....

Logcat:

上述代码中添加了必要的行号作为注释。

11-22 00:16:34.365: W/dalvikvm(1105): threadid=1: thread exiting with uncaught exception (group=0x41f342a0)
11-22 00:16:34.370: E/AndroidRuntime(1105): FATAL EXCEPTION: main
11-22 00:16:34.370: E/AndroidRuntime(1105): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@43304558 is not valid; is your activity running?
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.view.ViewRootImpl.setView(ViewRootImpl.java:708)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:346)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.view.Window$LocalWindowManager.addView(Window.java:554)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.app.Dialog.show(Dialog.java:277)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at com.app.abc.Game_shooting_AB.replay_dialog(Game_shooting_AB.java:431)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at com.app.abc.SpotOnView$MyCountDownTimer.onFinish(SpotOnView.java:181)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:118)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.os.Looper.loop(Looper.java:137)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at android.app.ActivityThread.main(ActivityThread.java:4898)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at java.lang.reflect.Method.invokeNative(Native Method)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at java.lang.reflect.Method.invoke(Method.java:511)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
11-22 00:16:34.370: E/AndroidRuntime(1105):     at dalvik.system.NativeStart.main(Native Method)

问题:

logcat 显示 您的活动正在进行吗?

  1. 我知道对话框需要有一个基础才能显示。但是如何修改代码呢?

  2. 是否可以在SpotOnView 中编写代码并显示对话框,而不是在Game_shooting_AB 代码中编写?

  3. 我尝试通过将类 MyCountDownTimer 和方法 replay_dialog 移回 Game_shooting_AB 来修改代码,但仍然出现相同的错误。我想问一下 MyCountDownTimer 的 OnFinish 是否会导致 Activity 完成,从而使对话框无法找到要显示的基础?

非常感谢!!

【问题讨论】:

    标签: android dialog window activity-finish


    【解决方案1】:

    问题从“((Game_shooting_AB)getContext()).replay_dialog();”开始这行代码。

    当您从视图内部调用 getContext() 时,您会从 android 文档中找到“视图的上下文”。现在您正在做的是将该上下文转换为 Game_shooting_AB 这不好,因为这可能是也可能不是 Activity 的上下文。 结帐Romain Guy's answer 关于这个。 因此,android 会告诉您“您的活动正在运行吗?”。

    现在要解决您当前的问题,您可以通过任何公共方法将您的活动实例传递给此视图,并将其存储在局部变量中。

    像这样调整你的代码:

    public class SpotOnView extends View 
    {
      Game_shooting_AB mGame_shooting_AB;
      public void setGame_shooting_AB(Game_shooting_AB mGame_shooting_AB){
       this.mGame_shooting_AB = mGame_shooting_AB;
      }
       ......
       // constructs a new SpotOnView
      public SpotOnView(Context context, RelativeLayout parentLayout)
      {
       super(context);          
       resources = context.getResources();            
        layoutInflater = (LayoutInflater)          context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      ....    
    
      } 
    
    
      public void start_timer() 
      {
        if (!timerHasStarted) 
        {
            countDownTimer.start();
            timerHasStarted = true;
        } 
        else 
        {
            countDownTimer.cancel();
            timerHasStarted = false;
        }
      }
    
    public class MyCountDownTimer extends CountDownTimer 
    {
        public MyCountDownTimer(long startTime, long interval) 
        {
            super(startTime, interval);
        }
    
        @Override
        public void onFinish() 
        {
            text.setText("Time's up!");
               mGame_shooting_AB.replay_dialog();  //LINE 181
        }
    
        @Override
        public void onTick(long millisUntilFinished) 
        {
            ....
        }
    }
    

    获得 SpotOnView 的实例后设置活动:

          view = new SpotOnView(this, layout);                                          //EXTENDING HERE
      layout.addView(view, 0); // add view to the layout
      view.setGame_shooting_AB(Game_shooting_AB.this);
    

    希望这会有所帮助。

    【讨论】:

    • 感谢您的及时回复!我想问在哪里可以拨打setGame_shooting_AB?它现在显示 java.lang.NullPointerException
    • 您应该将 setGame_shooting_AB 方法添加到您的 SpotOnView 类中。获取 SpotOnView 的实例后,通过将活动作为参数传递来调用此方法。
    • 非常抱歉,我还是被卡住了……你能用上面的编码更详细地编码吗? =(我不断让 NPE 到处尝试......
    • 您是如何在 UI 中添加 SpotOnView 的?使用布局还是在执行 new SpotView( .... 后添加视图?
    • 非常感谢您的热心支持!我已经在上面的 Game_shooting_AB 代码区添加了代码..通过创建一个新的 SpotOnView 并将其添加到 RelativeLayout
    【解决方案2】:

    您需要在完成活动时在 Intent 中使用setResult。然后需要在onActivityResult 的父活动中处理此结果,然后显示对话框。

    【讨论】:

    • 我现在已经修改了代码并将MyCountDownTimer 类和replay_dialog 方法移回Game_shooting_AB,但仍然出现同样的错误。我想问一下 MyCountDownTimer 的OnFinish 是否会导致 Activity 结束,从而使对话框无法找到要显示的基础?
    猜你喜欢
    • 2011-11-16
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多