I developed a game that use 2 textures (one is 2048x2048 and other is 1024x2048) beside that i use 7 background pictures as level images (each 640x960).
i got Out of Memory (OOM) when payment successful is pop out (inapp billing), i traced the log and got that the error is come out when it run onSurfaceCreated where the code assets.reload executed where all my textures and background pictures is reloaded.
don't know what to do since if i don't reload i will not get proper image.
FYI : assets.reload is called also when pause/resume executed (when i pressed home button while playing) but it never become problem.
public class Texture {
GLGraphics glGraphics;
FileIO fileIO;
String fileName;
int textureId;
int minFilter;
int magFilter;
int width;
int height;
public Texture(GLGame glGame, String fileName) {
this.glGraphics = glGame.getGLGraphics();
this.fileIO = glGame.getFileIO();
this.fileName = fileName;
load();
}
private void load() {
GL10 gl = glGraphics.getGL();
int[] textureIds = new int[1];
gl.glGenTextures(1, textureIds, 0);
textureId = textureIds[0];
InputStream in = null;
try {
in = fileIO.readAsset(fileName);
Bitmap bitmap = BitmapFactory.decodeStream(in);
width = bitmap.getWidth();
height = bitmap.getHeight();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
} catch(IOException e) {
throw new RuntimeException("Couldn't load texture '" + fileName + "'", e);
} finally {
if(in != null)
try { in.close(); } catch (IOException e) { }
}
}
public void reload() {
load();
bind();
setFilters(minFilter, magFilter);
glGraphics.getGL().glBindTexture(GL10.GL_TEXTURE_2D, 0);
}
public void setFilters(int minFilter, int magFilter) {
this.minFilter = minFilter;
this.magFilter = magFilter;
GL10 gl = glGraphics.getGL();
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter);
}
public void bind() {
GL10 gl = glGraphics.getGL();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
}
public void dispose() {
GL10 gl = glGraphics.getGL();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
int[] textureIds = { textureId };
gl.glDeleteTextures(1, textureIds, 0);
}
}
as you can see at the code (this is from mario zachner beginning android games framework) , assets.reload come from this texture.reload.
OOM happened in real devices (tested on samsung galaxy young and samsung galaxy note II)
additional question : does purchase process forced the app to enter pause mode ?
UPDATED / RESPONSE TO ANSWER : as per your suggestion, i modified the code :
in = fileIO.readAsset(fileName);
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(in,null,bfOptions);
int imageHeight = bfOptions.outHeight;
int imageWidth = bfOptions.outWidth;
bfOptions.inJustDecodeBounds = false;
bfOptions.inSampleSize = calculateInSampleSize(bfOptions,imageWidth,imageHeight);
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
bitmap = BitmapFactory.decodeStream(in,null,bfOptions);
width = bitmap.getWidth();
height = bitmap.getHeight();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
However when it run i got other error : still OOM but, it said failed for allocation scaled bitmap