1

I have an view called SpotOnView, and is extending on Game_shooting_AB. Coding as follows.

Background:

In the SpotOnView there is a countdown timer. When the time is up, the game is over, and a dialog box will popup to ask whether the user would like to quit or play again.

SpotOnView Code:

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 Code:

   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:

The necessary line numbers have added as comment in the above codes.

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)

Question:

The logcat shows is your activity running?

  1. I know that the dialog need to have a base to showup. But how could the code be modified?

  2. Would it be possible to code and show the dialog in the SpotOnView instead of writing in the Game_shooting_AB code?

  3. I have tried to modify the code by moving the class MyCountDownTimer and method replay_dialog back to Game_shooting_AB, but the same error still comes out. I would like to ask whether the OnFinish of the MyCountDownTimer will bring the Activity to finish such that the dialog does not able to find base to be shown on?

Thanks so much!!

pearmak
  • 4,979
  • 15
  • 64
  • 122

2 Answers2

1

The problem started from "((Game_shooting_AB)getContext()).replay_dialog();" this line of code.

As you will find from documentation of android when you call getContext() from inside of a view you get "The view's Context.". Now what you are doing is casting that context to Game_shooting_AB which is not good since that might or might not be the Activity's context. Checkout Romain Guy's answer about this. Thus android is telling you "is your activity running?".

Now to solve your current problem you can pass your activity instance to this view via any public method and have it store in a local variable.

Adjust your code like this:

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) 
    {
        ....
    }
}

After you get the instance of SpotOnView set the activity:

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

Hope this helps.

Community
  • 1
  • 1
saiful103a
  • 1,109
  • 7
  • 13
  • Thanks for your prompt response! I would like to ask where to call for the `setGame_shooting_AB`? It now shows java.lang.NullPointerException – pearmak Nov 21 '13 at 17:29
  • You should add setGame_shooting_AB method to your SpotOnView class.After getting the instance of SpotOnView call this this method by passing the activity as the parameter. – saiful103a Nov 21 '13 at 17:35
  • terribly sorry I am still got stucked...could you please code out in more details with the above coding? =( I keep on getting NPE trying everywhere... – pearmak Nov 21 '13 at 17:43
  • How did you add your SpotOnView in the UI? Using layout or did you addView after doing new SpotView( .... ? – saiful103a Nov 21 '13 at 17:46
  • really thanks for your keen support! I have added the codes in the above Game_shooting_AB code area..by creating a new SpotOnView and add it to the RelativeLayout – pearmak Nov 21 '13 at 17:49
  • made an edit for your convenience check if it works. though it should :) – saiful103a Nov 21 '13 at 17:56
  • my original code previously 50% chance can run while 50% fails. now implementing yours, i have tried about 10 times without getting error! thanks a lot! i will keep testing and may I contact you when it has problems =) =) – pearmak Nov 21 '13 at 18:04
  • I might've been wrong about "that definitely is not the Activity's context" part. Edited my answer and referenced one useful link for better understanding, so later on others don't get the wrong idea. Thanks – saiful103a Nov 21 '13 at 18:33
  • Hi I found that the problem still occurs after testing around 20 times...! with exactly the same error... – pearmak Nov 22 '13 at 15:03
  • what exception are you getting? – saiful103a Nov 22 '13 at 15:05
  • i was going to propose another solution but it is a bit long explanation. i think better if we move our discussion into chat? – saiful103a Nov 22 '13 at 15:08
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/41715/discussion-between-saiful103a-and-pearmak) – saiful103a Nov 22 '13 at 15:08
  • thanks for you final suggestion of adding a countDownTimer.cancel();countDownTimer = null; when calling for intent to finish the activity. It now works perfectly! – pearmak Nov 22 '13 at 15:43
0

You need to use setResult in Intent while finishing the activity. This result then needs to be handled in the parent activity in onActivityResult and then dialog be shown.

PravinCG
  • 7,688
  • 3
  • 30
  • 55
  • I have modified the code now and have move the class `MyCountDownTimer` and method `replay_dialog` back to `Game_shooting_AB`, but the same error still comes out. I would like to ask whether the `OnFinish` of the MyCountDownTimer will bring the Activity to finish such that the dialog does not able to find base to be shown on? – pearmak Nov 21 '13 at 16:59