ImagineThat ImagineThat - 8 months ago 36
Android Question

Saving and restoring ArrayList

My app takes two pictures and puts each URI into an ArrayList so that I can iterate it through it from a single ImageView. I know that the URIs are properly working and being added to the ArrayList. I assume that the activity dies on screen rotate for the camera (to take previously mentioned images) so I used onSaveInstanceState to keep the data I want to use. Before I did this, the app would crash right after taking the pictures. Now it doesn't, but I get a NullPointer when I try to setImage from the list. Am I doing something wrong?


Process: my.package.myapplication, PID: 15047
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageURI(' on a null object reference
at my.package.myapplication.Person1Screen$5.onClick(
at android.view.View.performClick(
at android.view.View$
at android.os.Handler.handleCallback(
at android.os.Handler.dispatchMessage(
at android.os.Looper.loop(
at java.lang.reflect.Method.invoke(Native Method)

I get the NullPointer in the setImageURI at the bottom of the following:

happy = (Button) findViewById(;
happy.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
id = HAPPY;
//picture mode
else if(!toggled) {
//display mode
//happyIndex = 0;
mainView.setImageURI(happyList.get(0)); // LINE 130

I have the following in my onCreate:

happyList = new ArrayList<>();
if (savedInstanceState != null) {
happyList = savedInstanceState.getParcelableArrayList(HAPPY_LIST);

My onSaveInstance:

public void onSaveInstanceState (Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(HAPPY_LIST, happyList);

My TakePictureIntent (to take two pictures either from camera or gallery) and onActivityResult (takes URIs and adds to list):

private void dispatchTakePictureIntent() {
pictureCounter = -1;
for(int i = 0; i < 2; i++) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
outputFileUri = Uri.fromFile(photoFile);
} catch (IOException ex) {
}catch (NullPointerException nullEx) {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName,;
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
// Filesystem.
final Intent galleryIntent = new Intent();
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
startActivityForResult(chooserIntent, REQUEST_TAKE_PHOTO);

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_TAKE_PHOTO) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else {
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri selectedImageUri;
if (isCamera) {
selectedImageUri = outputFileUri;
} else {
selectedImageUri = data == null ? null : data.getData();
// mainView.setImageURI(selectedImageUri);
// Log.d("Before adding", selectedImageUri.toString());
// Log.d("Array:", happyList.toString());


Firstly, it's recommended you store a key constant in your class. Main reason, to keep them consistent and avoid typos.

public static final String HAPPY_LIST = "happyList";

Now, use that whenever you save and restore

Second, I think these should be flipped because you want to put in the things you save, then do whatever the super call does

Also Uri objects are Parcelable, so use the appropriate method for that

public void onSaveInstanceState (Bundle savedInstanceState) {
    savedInstanceState.putParcelableArrayList(HAPPY_LIST, happyList);

Finally, you can either use the restored bundle in onRestoreInstanceState or in onCreate, but I don't think you need to do both.