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
3.0
iwg..ic 12 years ago
parent 5a90cd7082
commit 1df4fe8346
  1. 42
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 2
      engine/src/android/com/jme3/audio/android/AndroidAudioRenderer.java
  3. 17
      engine/src/android/com/jme3/input/android/AndroidInput.java
  4. 27
      engine/src/android/com/jme3/input/android/AndroidSensorJoyInput.java
  5. 26
      engine/src/android/com/jme3/system/android/OGLESContext.java

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

@ -64,7 +64,6 @@ public class AndroidAudioRenderer implements AudioRenderer,
private final Vector3f listenerPosition = new Vector3f(); private final Vector3f listenerPosition = new Vector3f();
// For temp use // For temp use
private final Vector3f distanceVector = new Vector3f(); private final Vector3f distanceVector = new Vector3f();
private final Context context;
private final AssetManager assetManager; private final AssetManager assetManager;
private HashMap<Integer, AudioNode> soundpoolStillLoading = new HashMap<Integer, AudioNode>(); private HashMap<Integer, AudioNode> soundpoolStillLoading = new HashMap<Integer, AudioNode>();
private Listener listener; private Listener listener;
@ -72,7 +71,6 @@ public class AndroidAudioRenderer implements AudioRenderer,
private final AudioManager manager; private final AudioManager manager;
public AndroidAudioRenderer(Activity context) { public AndroidAudioRenderer(Activity context) {
this.context = context;
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
context.setVolumeControlStream(AudioManager.STREAM_MUSIC); context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
assetManager = context.getAssets(); assetManager = context.getAssets();

@ -12,7 +12,6 @@ import com.jme3.math.Vector2f;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import com.jme3.util.RingBuffer; import com.jme3.util.RingBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
@ -148,16 +147,17 @@ public class AndroidInput implements
0x0,//mute 0x0,//mute
}; };
public AndroidInput(View view) { public AndroidInput() {
setView(view);
detector = new GestureDetector(null, this, null, false);
scaledetector = new ScaleGestureDetector(view.getContext(), this);
} }
public void setView(View view) { public void setView(View view) {
this.view = view; this.view = view;
this.view.setOnTouchListener(this); if (view != null) {
this.view.setOnKeyListener(this); detector = new GestureDetector(null, this, null, false);
scaledetector = new ScaleGestureDetector(view.getContext(), this);
view.setOnTouchListener(this);
view.setOnKeyListener(this);
}
} }
private TouchEvent getNextFreeTouchEvent() { private TouchEvent getNextFreeTouchEvent() {
@ -373,6 +373,9 @@ public class AndroidInput implements
while (!eventQueue.isEmpty()) { while (!eventQueue.isEmpty()) {
eventQueue.pop(); eventQueue.pop();
} }
this.view = null;
} }
@Override @Override

@ -32,15 +32,15 @@
package com.jme3.input.android; package com.jme3.input.android;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.os.Vibrator; import android.os.Vibrator;
import android.view.Display;
import android.view.Surface; import android.view.Surface;
import android.view.WindowManager; import android.view.View;
import com.jme3.input.AbstractJoystick; import com.jme3.input.AbstractJoystick;
import com.jme3.input.DefaultJoystickAxis; import com.jme3.input.DefaultJoystickAxis;
import com.jme3.input.InputManager; import com.jme3.input.InputManager;
@ -98,6 +98,7 @@ import java.util.logging.Logger;
public class AndroidSensorJoyInput implements JoyInput, SensorEventListener { public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
private final static Logger logger = Logger.getLogger(AndroidSensorJoyInput.class.getName()); private final static Logger logger = Logger.getLogger(AndroidSensorJoyInput.class.getName());
private Activity activity = null;
private InputManager inputManager = null; private InputManager inputManager = null;
private SensorManager sensorManager = null; private SensorManager sensorManager = null;
private Vibrator vibrator = null; private Vibrator vibrator = null;
@ -106,8 +107,6 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
private RawInputListener listener = null; private RawInputListener listener = null;
private IntMap<SensorData> sensors = new IntMap<SensorData>(); private IntMap<SensorData> sensors = new IntMap<SensorData>();
private AndroidJoystick[] joysticks; private AndroidJoystick[] joysticks;
private WindowManager window;
private Display disp;
private int lastRotation = 0; private int lastRotation = 0;
private boolean initialized = false; private boolean initialized = false;
private boolean loaded = false; private boolean loaded = false;
@ -136,25 +135,16 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
} }
private void initSensorManager() { private void initSensorManager() {
initWindow(); this.activity = JmeAndroidSystem.getActivity();
// Get instance of the SensorManager from the current Context // 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 // 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) { if (vibrator == null) {
logger.log(Level.INFO, "Vibrator Service not found."); 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) { private SensorData initSensor(int sensorType) {
boolean success = false; boolean success = false;
@ -316,7 +306,7 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
* @return Current device rotation amount * @return Current device rotation amount
*/ */
private int getScreenRotation() { private int getScreenRotation() {
return disp.getRotation(); return activity.getWindowManager().getDefaultDisplay().getRotation();
} }
/** /**
@ -600,6 +590,9 @@ public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
initialized = false; initialized = false;
loaded = false; loaded = false;
joysticks = null; joysticks = null;
sensorManager = null;
vibrator = null;
activity = null;
} }
public boolean isInitialized() { public boolean isInitialized() {

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

Loading…
Cancel
Save