Parcourir la source

Attempt to clean up some references to help with out of memory issues on second start of app on Android

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10047 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
iwg..ic il y a 12 ans
Parent
commit
1df4fe8346

+ 24 - 20
engine/src/android/com/jme3/app/AndroidHarness.java

@@ -6,7 +6,6 @@ import android.content.DialogInterface;
 import android.content.pm.ActivityInfo;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
-import android.opengl.GLSurfaceView;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.*;
@@ -14,6 +13,7 @@ import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
+import com.jme3.asset.DesktopAssetManager;
 import com.jme3.audio.AudioRenderer;
 import com.jme3.audio.android.AndroidAudioRenderer;
 import com.jme3.input.JoyInput;
@@ -22,6 +22,7 @@ import com.jme3.input.android.AndroidSensorJoyInput;
 import com.jme3.input.controls.TouchListener;
 import com.jme3.input.controls.TouchTrigger;
 import com.jme3.input.event.TouchEvent;
+import com.jme3.renderer.android.AndroidGLSurfaceView;
 import com.jme3.system.AppSettings;
 import com.jme3.system.SystemListener;
 import com.jme3.system.android.AndroidConfigChooser.ConfigType;
@@ -141,7 +142,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
      */
     protected int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
     protected OGLESContext ctx;
-    protected GLSurfaceView view = null;
+    protected AndroidGLSurfaceView view = null;
     protected boolean isGLThreadPaused = true;
     protected ImageView splashImageView = null;
     protected FrameLayout frameLayout = null;
@@ -155,7 +156,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
 
     @Override
     public Object onRetainNonConfigurationInstance() {
-        logger.log(Level.INFO, "onRetainNonConfigurationInstance called");
+        logger.log(Level.INFO, "onRetainNonConfigurationInstance");
         final DataObject data = new DataObject();
         data.app = this.app;
         inConfigChange = true;
@@ -165,6 +166,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
+        logger.info("onCreate");
         super.onCreate(savedInstanceState);
 
         JmeAndroidSystem.setActivity(this);
@@ -185,18 +187,13 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
             logger.log(Level.INFO, "Using Retained App");
             this.app = data.app;
 
-            ctx = (OGLESContext) app.getContext();
-            view = ctx.createView(eglConfigType, eglConfigVerboseLogging);
-            ctx.setSystemListener(this);
-            layoutDisplay();
-
         } else {
             // Discover the screen reolution
             //TODO try to find a better way to get a hand on the resolution
             WindowManager wind = this.getWindowManager();
             Display disp = wind.getDefaultDisplay();
             Log.d("AndroidHarness", "Resolution from Window, width:" + disp.getWidth() + ", height: " + disp.getHeight());
-                
+
             // Create Settings
             logger.log(Level.INFO, "Creating settings");
             AppSettings settings = new AppSettings(true);
@@ -215,38 +212,41 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
 
                 app.setSettings(settings);
                 app.start();
-                ctx = (OGLESContext) app.getContext();
-                view = ctx.createView(eglConfigType, eglConfigVerboseLogging);
 
-                // AndroidHarness wraps the app as a SystemListener.
-                ctx.setSystemListener(this);
-                layoutDisplay();
 
             } catch (Exception ex) {
                 handleError("Class " + appClass + " init failed", ex);
                 setContentView(new TextView(this));
             }
         }
+
+        ctx = (OGLESContext) app.getContext();
+        view = ctx.createView(eglConfigType, eglConfigVerboseLogging);
+        // AndroidHarness wraps the app as a SystemListener.
+        ctx.setSystemListener(this);
+        layoutDisplay();
+
     }
 
     @Override
     protected void onRestart() {
+        logger.info("onRestart");
         super.onRestart();
         if (app != null) {
             app.restart();
         }
 
-        logger.info("onRestart");
     }
 
     @Override
     protected void onStart() {
-        super.onStart();
         logger.info("onStart");
+        super.onStart();
     }
 
     @Override
     protected void onResume() {
+        logger.info("onResume");
         super.onResume();
         if (view != null) {
             view.onResume();
@@ -274,11 +274,11 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
         }
 
         isGLThreadPaused = false;
-        logger.info("onResume");
     }
 
     @Override
     protected void onPause() {
+        logger.info("onPause");
         super.onPause();
         if (view != null) {
             view.onPause();
@@ -306,18 +306,18 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
             }
         }
         isGLThreadPaused = true;
-        logger.info("onPause");
 
     }
 
     @Override
     protected void onStop() {
-        super.onStop();
         logger.info("onStop");
+        super.onStop();
     }
 
     @Override
     protected void onDestroy() {
+        logger.info("onDestroy");
         final DataObject data = (DataObject) getLastNonConfigurationInstance();
         if (data != null || inConfigChange) {
             logger.info("In Config Change, not stopping app.");
@@ -326,7 +326,11 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
                 app.stop(!isGLThreadPaused);
             }
         }
-        logger.info("onDestroy");
+        JmeAndroidSystem.setActivity(null);
+        ctx = null;
+        app = null;
+        view = null;
+
         super.onDestroy();
     }
 

+ 4 - 6
engine/src/android/com/jme3/audio/android/AndroidAudioRenderer.java

@@ -50,7 +50,7 @@ import java.util.logging.Logger;
 
 /**
  * This class is the android implementation for {@link AudioRenderer}
- * 
+ *
  * @author larynx
  * @author plan_rich
  */
@@ -64,7 +64,6 @@ public class AndroidAudioRenderer implements AudioRenderer,
     private final Vector3f listenerPosition = new Vector3f();
     // For temp use
     private final Vector3f distanceVector = new Vector3f();
-    private final Context context;
     private final AssetManager assetManager;
     private HashMap<Integer, AudioNode> soundpoolStillLoading = new HashMap<Integer, AudioNode>();
     private Listener listener;
@@ -72,7 +71,6 @@ public class AndroidAudioRenderer implements AudioRenderer,
     private final AudioManager manager;
 
     public AndroidAudioRenderer(Activity context) {
-        this.context = context;
         manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
         assetManager = context.getAssets();
@@ -302,14 +300,14 @@ public class AndroidAudioRenderer implements AudioRenderer,
                     break;
                 }
             }
-        
+
     }
 
     /**
      * Plays using the {@link SoundPool} of Android. Due to hard limitation of
      * the SoundPool: After playing more instances of the sound you only have
      * the channel of the last played instance.
-     * 
+     *
      * It is not possible to get information about the state of the soundpool of
      * a specific streamid, so removing is not possilbe -> noone knows when
      * sound finished.
@@ -329,7 +327,7 @@ public class AndroidAudioRenderer implements AudioRenderer,
 
         try {
 
-            if (audioData.getId() < 0) { // found something to load                                
+            if (audioData.getId() < 0) { // found something to load
                 int soundId = soundPool.load(
                         assetManager.openFd(assetKey.getName()), 1);
                 audioData.setId(soundId);

+ 15 - 12
engine/src/android/com/jme3/input/android/AndroidInput.java

@@ -12,7 +12,6 @@ import com.jme3.math.Vector2f;
 import com.jme3.system.AppSettings;
 import com.jme3.util.RingBuffer;
 import java.util.HashMap;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -148,16 +147,17 @@ public class AndroidInput implements
         0x0,//mute
     };
 
-    public AndroidInput(View view) {
-        setView(view);
-        detector = new GestureDetector(null, this, null, false);
-        scaledetector = new ScaleGestureDetector(view.getContext(), this);
+    public AndroidInput() {
     }
 
     public void setView(View view) {
         this.view = view;
-        this.view.setOnTouchListener(this);
-        this.view.setOnKeyListener(this);
+        if (view != null) {
+            detector = new GestureDetector(null, this, null, false);
+            scaledetector = new ScaleGestureDetector(view.getContext(), this);
+            view.setOnTouchListener(this);
+            view.setOnKeyListener(this);
+        }
     }
 
     private TouchEvent getNextFreeTouchEvent() {
@@ -373,6 +373,9 @@ public class AndroidInput implements
         while (!eventQueue.isEmpty()) {
             eventQueue.pop();
         }
+
+
+        this.view = null;
     }
 
     @Override
@@ -464,14 +467,14 @@ public class AndroidInput implements
                                 listener.onMouseMotionEvent(mot);
                                 lastX = newX;
                                 lastY = newY;
-                                
+
                                 break;
-                                
+
                             case MOVE:
                                 if (event.isScaleSpanInProgress()) {
                                     break;
                                 }
-                                
+
                                 int dx;
                                 int dy;
                                 if (lastX != -1) {
@@ -481,13 +484,13 @@ public class AndroidInput implements
                                     dx = 0;
                                     dy = 0;
                                 }
-                                
+
                                 mot = new MouseMotionEvent(newX, newY, dx, dy, (int)event.getScaleSpan(), (int)event.getDeltaScaleSpan());
                                 mot.setTime(event.getTime());
                                 listener.onMouseMotionEvent(mot);
                                 lastX = newX;
                                 lastY = newY;
-                                
+
                                 break;
                         }
                     }

+ 48 - 55
engine/src/android/com/jme3/input/android/AndroidSensorJoyInput.java

@@ -32,15 +32,15 @@
 
 package com.jme3.input.android;
 
+import android.app.Activity;
 import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.os.Vibrator;
-import android.view.Display;
 import android.view.Surface;
-import android.view.WindowManager;
+import android.view.View;
 import com.jme3.input.AbstractJoystick;
 import com.jme3.input.DefaultJoystickAxis;
 import com.jme3.input.InputManager;
@@ -63,20 +63,20 @@ import java.util.logging.Logger;
  * AndroidSensorJoyInput converts the Android Sensor system into Joystick events.
  * A single joystick is configured and includes data for all configured sensors
  * as seperate axes of the joystick.
- * 
+ *
  * Each axis is named accounting to the static strings in SensorJoystickAxis.
  * Refer to the strings defined in SensorJoystickAxis for a list of supported
  * sensors and their axis data.  Each sensor type defined in SensorJoystickAxis
  * will be attempted to be configured.  If the device does not support a particular
  * sensor, the axis will return null if joystick.getAxis(String name) is called.
- * 
+ *
  * The joystick.getXAxis and getYAxis methods of the joystick are configured to
  * return the device orientation values in the device's X and Y directions.
- * 
+ *
  * This joystick also supports the joystick.rumble(rumbleAmount) method.  In this
  * case, when joystick.rumble(rumbleAmount) is called, the Android device will vibrate
  * if the device has a built in vibrate motor.
- * 
+ *
  * Because Andorid does not allow for the user to define the intensity of the
  * vibration, the rumble amount (ie strength) is converted into vibration pulses
  * The stronger the strength amount, the shorter the delay between pulses.  If
@@ -92,12 +92,13 @@ import java.util.logging.Logger;
  * To use the joystick rumble feature, the following line needs to be
  * added to the Android Manifest File
  *     <uses-permission android:name="android.permission.VIBRATE"/>
- * 
+ *
  * @author iwgeric
  */
 public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
     private final static Logger logger = Logger.getLogger(AndroidSensorJoyInput.class.getName());
 
+    private Activity activity = null;
     private InputManager inputManager = null;
     private SensorManager sensorManager = null;
     private Vibrator vibrator = null;
@@ -106,8 +107,6 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
     private RawInputListener listener = null;
     private IntMap<SensorData> sensors = new IntMap<SensorData>();
     private AndroidJoystick[] joysticks;
-    private WindowManager window;
-    private Display disp;
     private int lastRotation = 0;
     private boolean initialized = false;
     private boolean loaded = false;
@@ -136,25 +135,16 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
     }
 
     private void initSensorManager() {
-        initWindow();
+        this.activity = JmeAndroidSystem.getActivity();
         // Get instance of the SensorManager from the current Context
-        sensorManager = (SensorManager) JmeAndroidSystem.getActivity().getSystemService(Context.SENSOR_SERVICE);
+        sensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
         // Get instance of Vibrator from current Context
-        vibrator = (Vibrator) JmeAndroidSystem.getActivity().getSystemService(Context.VIBRATOR_SERVICE);
+        vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
         if (vibrator == null) {
             logger.log(Level.INFO, "Vibrator Service not found.");
         }
     }
 
-    /**
-     * Used internally.  Do not use.
-     * Allows the context to reset the current activity for getting device rotation
-     */
-    public void initWindow() {
-        window = JmeAndroidSystem.getActivity().getWindowManager();
-        disp = window.getDefaultDisplay();
-    }
-
     private SensorData initSensor(int sensorType) {
         boolean success = false;
 
@@ -316,7 +306,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
      * @return Current device rotation amount
      */
     private int getScreenRotation() {
-        return disp.getRotation();
+        return activity.getWindowManager().getDefaultDisplay().getRotation();
     }
 
     /**
@@ -364,7 +354,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
         if (sensorData.sensorAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
             return false;
         }
-        
+
         synchronized(sensorData.valuesLock) {
             accValues[0] = sensorData.lastValues[0];
             accValues[1] = sensorData.lastValues[1];
@@ -379,7 +369,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
         if (sensorData.sensorAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
             return false;
         }
-        
+
         synchronized(sensorData.valuesLock) {
             magValues[0] = sensorData.lastValues[0];
             magValues[1] = sensorData.lastValues[1];
@@ -464,9 +454,9 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
 
     public Joystick[] loadJoysticks(InputManager inputManager) {
         this.inputManager = inputManager;
-        
+
         initSensorManager();
-        
+
         SensorData sensorData;
         List<Joystick> list = new ArrayList<Joystick>();
         AndroidJoystick joystick;
@@ -477,7 +467,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
                                     list.size(),
                                     "AndroidSensorsJoystick");
         list.add(joystick);
-        
+
         List<Sensor> availSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
         for (Sensor sensor: availSensors) {
             logger.log(Level.INFO, "{0} Sensor is available, Type: {1}, Vendor: {2}, Version: {3}",
@@ -561,8 +551,8 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
 //        if (sensorData != null) {
 //            sensorData.lastValues = new float[1];
 //        }
-        
-    
+
+
         joysticks = list.toArray( new AndroidJoystick[list.size()] );
         loaded = true;
         return joysticks;
@@ -600,6 +590,9 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
         initialized = false;
         loaded = false;
         joysticks = null;
+        sensorManager = null;
+        vibrator = null;
+        activity = null;
     }
 
     public boolean isInitialized() {
@@ -636,7 +629,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
                     sensorData.lastValues[i] = se.values[i];
                 }
             }
-            
+
             if (sensorData != null && sensorData.axes.size() > 0) {
                 AndroidJoystickAxis axis;
                 for (int i=0; i<se.values.length; i++) {
@@ -686,21 +679,21 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
 
         public AndroidJoystick( InputManager inputManager, JoyInput joyInput,
                                 int joyId, String name){
-            
-            super( inputManager, joyInput, joyId, name );                                
-            
-            this.nullAxis = new DefaultJoystickAxis( getInputManager(), this, -1, 
+
+            super( inputManager, joyInput, joyId, name );
+
+            this.nullAxis = new DefaultJoystickAxis( getInputManager(), this, -1,
                                                      "Null", "null", false, false, 0 );
-            this.xAxis = nullAxis;                                                     
-            this.yAxis = nullAxis;                                                     
+            this.xAxis = nullAxis;
+            this.yAxis = nullAxis;
             this.povX = nullAxis;
-            this.povY = nullAxis;                                                     
-            
+            this.povY = nullAxis;
+
         }
-        
+
         protected AndroidJoystickAxis addAxis(String axisName, String logicalName, int axisNum, float maxRawValue) {
             AndroidJoystickAxis axis;
-            
+
             axis = new AndroidJoystickAxis(
                     inputManager,               // InputManager (InputManager)
                     this,                       // parent Joystick (Joystick)
@@ -711,33 +704,33 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
                     false,                      // isRelative (boolean)
                     0.01f,                      // Axis Deadzone (float)
                     maxRawValue);               // Axis Max Raw Value (float)
-            
+
             super.addAxis(axis);
-            
+
             return axis;
         }
-        
+
         protected void setXAxis(JoystickAxis axis) {
             xAxis = axis;
         }
         protected void setYAxis(JoystickAxis axis) {
             yAxis = axis;
         }
-        
+
         @Override
         public JoystickAxis getXAxis() {
             return xAxis;
-        }     
+        }
 
         @Override
         public JoystickAxis getYAxis() {
             return yAxis;
-        }     
+        }
 
         @Override
         public JoystickAxis getPovXAxis() {
             return povX;
-        }     
+        }
 
         @Override
         public JoystickAxis getPovYAxis() {
@@ -745,7 +738,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
         }
 
     }
-    
+
     public class AndroidJoystickAxis extends DefaultJoystickAxis implements SensorJoystickAxis {
         float zeroRawValue = 0f;
         float curRawValue = 0f;
@@ -756,10 +749,10 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
 
         public AndroidJoystickAxis(InputManager inputManager, Joystick parent,
                            int axisIndex, String name, String logicalId,
-                           boolean isAnalog, boolean isRelative, float deadZone, 
+                           boolean isAnalog, boolean isRelative, float deadZone,
                            float maxRawValue) {
             super(inputManager, parent, axisIndex, name, logicalId, isAnalog, isRelative, deadZone);
-            
+
             this.maxRawValue = maxRawValue;
         }
 
@@ -770,7 +763,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
         public void setMaxRawValue(float maxRawValue) {
             this.maxRawValue = maxRawValue;
         }
-        
+
         protected float getLastRawValue() {
             return lastRawValue;
         }
@@ -783,18 +776,18 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
                 hasChanged = false;
             }
         }
-        
+
         protected float getJoystickAxisValue() {
             return (lastRawValue-zeroRawValue) / maxRawValue;
         }
-        
+
         protected boolean isChanged() {
             return hasChanged;
         }
-        
+
         public void calibrateCenter() {
             zeroRawValue = lastRawValue;
-            logger.log(Level.INFO, "Calibrating axis {0} to {1}", 
+            logger.log(Level.INFO, "Calibrating axis {0} to {1}",
                     new Object[]{getName(), zeroRawValue});
         }
 

+ 11 - 15
engine/src/android/com/jme3/system/android/OGLESContext.java

@@ -31,6 +31,7 @@
  */
 package com.jme3.system.android;
 
+import android.app.Activity;
 import com.jme3.renderer.android.AndroidGLSurfaceView;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
@@ -75,7 +76,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
     protected SystemListener listener;
     protected boolean autoFlush = true;
     protected AndroidInput androidInput;
-    protected AndroidGLSurfaceView view;
     protected int minFrameDuration = 0;                   // No FPS cap
     protected JoyInput androidSensorJoyInput = null;
     /**
@@ -107,20 +107,15 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
      * @param eglConfigVerboseLogging if true show all found configs
      * @return GLSurfaceView The newly created view
      */
-    public GLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
-        // if simulated joysticks are used, init the window to update the activity used to
-        // get the window orientation
-        if (androidSensorJoyInput != null && androidSensorJoyInput instanceof AndroidSensorJoyInput) {
-            ((AndroidSensorJoyInput)androidSensorJoyInput).initWindow();
-        }
+    public AndroidGLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
+        AndroidGLSurfaceView view;
 
         // Start to set up the view
-        view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity());
+        view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication());
         if (androidInput == null) {
-            androidInput = new AndroidInput(view);
-        } else {
-            androidInput.setView(view);
+            androidInput = new AndroidInput();
         }
+        androidInput.setView(view);
         androidInput.loadSettings(settings);
 
         if (configType == ConfigType.LEGACY) {
@@ -402,13 +397,14 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
         logger.log(Level.INFO, "requestDialog: title: {0}, initialValue: {1}",
                 new Object[]{title, initialValue});
 
-        JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {
+        final Activity activity = JmeAndroidSystem.getActivity();
+        activity.runOnUiThread(new Runnable() {
 
             @Override
             public void run() {
 
-                final FrameLayout layoutTextDialogInput = new FrameLayout(JmeAndroidSystem.getActivity());
-                final EditText editTextDialogInput = new EditText(JmeAndroidSystem.getActivity());
+                final FrameLayout layoutTextDialogInput = new FrameLayout(activity);
+                final EditText editTextDialogInput = new EditText(activity);
                 editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
                 editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
                 editTextDialogInput.setPadding(20, 20, 20, 20);
@@ -438,7 +434,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
 
                 layoutTextDialogInput.addView(editTextDialogInput);
 
-                AlertDialog dialogTextInput = new AlertDialog.Builder(JmeAndroidSystem.getActivity()).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
+                AlertDialog dialogTextInput = new AlertDialog.Builder(activity).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
                         new DialogInterface.OnClickListener() {
 
                             public void onClick(DialogInterface dialog, int whichButton) {