2013-11-21 56 views
1

我有一個視圖叫做SpotOnView,並且正在延伸到Game_shooting_AB。編碼如下。android:您的活動正在運行嗎?對話框無法在OnFinish上顯示

背景:

在SpotOnView中有一個倒數計時器。當時間到了,遊戲結束,會彈出一個對話框詢問用戶是否想要退出或再次玩遊戲。

SpotOnView代碼:

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 [email protected] 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完成,使得對話框無法找到要顯示的基礎?

非常感謝!

回答

1

問題從「((Game_shooting_AB)getContext())。」replay_dialog();「這行代碼。

正如您從android的文檔中發現的,當您從視圖內部調用getContext()時,您會看到「視圖的上下文」。現在你正在做的是將該上下文轉換爲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); 

希望這有助於。

+0

感謝您的及時響應!我想問問在哪裏調用'setGame_shooting_AB'?它現在顯示java.lang.NullPointerException – pearmak

+0

您應該將setGame_shooting_AB方法添加到您的SpotOnView類。獲得SpotOnView的實例後,通過傳遞該活動作爲參數來調用此方法。 – saiful103a

+0

非常抱歉,我仍然陷入困境......請問您能否使用上述代碼更詳細地編碼? =(我一直在努力讓NPE在任何地方嘗試...... – pearmak

0

您需要在完成活動時使用Intent中的setResult。這個結果需要在onActivityResult的父活動中處理,然後顯示對話框。

+0

我已經修改了代碼,並將類MyCountDownTimer和方法replay_dialog移回到Game_shooting_AB,但仍然出現同樣的錯誤。我想問一下MyCountDownTimer的OnFinish是否會使Activity完成,使對話框無法找到要顯示的基礎? – pearmak

相關問題