Vazamento de memória do Android, sem variáveis estáticas
Eu sou um desenvolvedor Android iniciante, e como um projeto prático, estou tentando fazer e atividade que pode tirar uma foto, salvá-lo para o armazenamento externo e exibi-lo em um ImageView. Quase tudo parece estar funcionando, no entanto, parece que tenho um vazamento de memória.
Quando a orientação da tela muda, acredito que a atividade é destruída e depois recriada. Para continuar exibindo a imagem, estou armazenando o caminho para a imagem como uma string em um pacote em onSaveInstanceState e redefinindo a imagem em onResotreInstanceState. Tirando 5mp fotos, posso girar a tela uma vez e, na segunda rotação, o aplicativo trava e o LogCat relata um erro de falta de memória. Com imagens de resolução mais baixa, obtenho mais rotações, mas o aplicativo ainda falha e obtenho o mesmo erro.
Eu tenho lido sobre vazamentos de memória do Android, e tudo parece dizer para não usar Drawables estáticos, que podem ter referências à visão, e impedir que o VM libere a memória. Tanto quanto eu posso dizer, eu não estou fazendo nada assim que continuaria segurando referências. Se alguém puder me ajudar a localizar meu erro, eu realmente aprecio isso. Aqui está o código:
public class CameraTestsActivity extends Activity {
private Uri fileUri;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void takePicture(View view){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputImageFileUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, 0);
}
private static Uri getOutputImageFileUri() {
return Uri.fromFile(getOutputImageFile());
}
private static File getOutputImageFile(){
Log.d("CameraTestsActivity", "Storage state: " + Environment.getExternalStorageState());
if (Environment.getExternalStorageState().equals("mounted")){
File mediaStorageDirs = new File (Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures" + "/CameraTestsActivity");
if (! mediaStorageDirs.exists()){
if (! mediaStorageDirs.mkdirs()){
Log.d("CameraTestsActivity", "Failed to create directories");
mediaStorageDirs = null;
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File imageFile = new File(mediaStorageDirs.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
mediaStorageDirs = null;
return imageFile;
}
Log.d("CameraTestsActivity", "Storage state bad");
return null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK){
if (requestCode == 0){
setImage();
}
}
else{
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
fileUri = Uri.parse(savedInstanceState.getString("uri"));
setImage();
super.onRestoreInstanceState(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("uri", fileUri.toString());
super.onSaveInstanceState(outState);
}
private void setImage(){
ImageView image = (ImageView)findViewById(R.id.imageView1);
File file = new File(fileUri.toString().substring(7));
if (!file.exists())
Log.d("CameraTestsActivity", "File " + fileUri.toString().substring(7) + "does not exist");
image.setImageURI(fileUri);
}
}