Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

View state lost between onActivityResult and onResume

I’m using startActivityForResult() to capture an image from the camera. While testing with the developer option “Don’t keep activities”, I noticed that my view state is being correctly restored in onViewStateRestored, but then is lost again before onActivityResult gets called. Looks like a second instance of the same fragment is being created; there are two calls to onCreate, one with a valid savedInstanceState, and another with savedInstanceState == null. The first one never gets to onResume.

This is what I see in the logs:

E/CaptureFragment﹕ fireTakePictureIntent: tempPhotoPath: /storage/emulated/0/Pictures/JPEG_2014-10-15 23.19.45.jpg
E/CaptureFragment﹕ startActivityForResult: tempPhotoPath: /storage/emulated/0/Pictures/JPEG_2014-10-15 23.19.45.jpg
I/am_on_paused_called﹕ [0,com.chimbori.galapagos.views.capture.CaptureActivity]
E/CaptureFragment﹕ onSaveInstanceState: tempPhotoPath: /storage/emulated/0/Pictures/JPEG_2014-10-15 23.19.45.jpg
E/CaptureFragment﹕ onCreate: tempPhotoPath: /storage/emulated/0/Pictures/JPEG_2014-10-15 23.19.45.jpg
E/CaptureFragment﹕ onViewStateRestored: tempPhotoPath: /storage/emulated/0/Pictures/JPEG_2014-10-15 23.19.45.jpg
E/CaptureFragment﹕ onCreate: tempPhotoPath: null
E/CaptureFragment﹕ onStart
E/CaptureFragment﹕ onActivityResult : tempPhotoPath: null
E/CaptureFragment﹕ onResume: tempPhotoPath: null
I/am_on_resume_called﹕ [0,com.chimbori.galapagos.views.capture.CaptureActivity]

The methods are straightforward:

private String tempPhotoPath;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  if (savedInstanceState != null && savedInstanceState.containsKey(IntentConstants.EXTRA_PHOTO_FILE)) {
    tempPhotoPath = savedInstanceState.getString(IntentConstants.EXTRA_PHOTO_FILE);
  }
  Log.e(TAG, "onCreate: tempPhotoPath: " + tempPhotoPath);
}

private void fireTakePictureIntent() {
  Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
    tempPhotoPath = FilePaths.createTempPhotoPath().getAbsolutePath();
    Log.e(TAG, "fireTakePictureIntent: tempPhotoPath: " + tempPhotoPath);
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(tempPhotoPath)));
    Log.e(TAG, "startActivityForResult: tempPhotoPath: " + tempPhotoPath);
    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
  }
}

@Override
public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if (tempPhotoPath != null) {
    Log.e(TAG, "onSaveInstanceState: tempPhotoPath: " + tempPhotoPath);
    outState.putString(IntentConstants.EXTRA_PHOTO_FILE, tempPhotoPath);
  }
}

@Override
public void onViewStateRestored(Bundle savedInstanceState) {
  super.onViewStateRestored(savedInstanceState);
  if (savedInstanceState != null && savedInstanceState.containsKey(IntentConstants.EXTRA_PHOTO_FILE)) {
    tempPhotoPath = savedInstanceState.getString(IntentConstants.EXTRA_PHOTO_FILE);
    Log.e(TAG, "onViewStateRestored: tempPhotoPath: " + tempPhotoPath);
  }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
    Log.e(TAG, "onActivityResult : tempPhotoPath: " + tempPhotoPath);
  }
}

Any ideas why it would get restored correctly on onViewStateRestored but go back to null in onActivityResult and beyond?

like image 779
Manas Tungare Avatar asked Dec 05 '25 19:12

Manas Tungare


1 Answers

OK, I figured it out. I was re-creating the CaptureFragment in the CaptureActivity even when I was being passed a non-null savedInstanceState. That explains why two fragments were being created instead of one.

Before fix: CaptureActivity.onCreate

CaptureFragment captureFragment = new CaptureFragment();
getFragmentManager().beginTransaction()
    .replace(R.id.activity_capture_content_frame, captureFragment,
        CaptureFragment.class.getCanonicalName())
    .commit();

Fixed:

CaptureFragment captureFragment = (savedInstanceState != null)
    ? (CaptureFragment) getFragmentManager().findFragmentByTag(CaptureFragment.class.getCanonicalName())
    : new CaptureFragment();
getFragmentManager().beginTransaction()
    .replace(R.id.activity_capture_content_frame, captureFragment,
        CaptureFragment.class.getCanonicalName())
    .commit();
like image 82
Manas Tungare Avatar answered Dec 08 '25 12:12

Manas Tungare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!