Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sane way to go from ArrayList<Long> through an Intent

I'm currently writing an app that pulls an array of longs from a server via json, and then passes that list from one activity into another. The basic skeleton looks like this:

public void onResponse(Map result)
{
    ArrayList handles= (ArrayList)result.get("fileHandles");

    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtra("handles", handles);
}

So the first problem becomes evident, the only methods for putExtra are putIntegerArrayListExtra, putStringArrayListExtra, putCharSequenceArrayListExtra, and putParcelableArrayListExtra. Thinking Long would probably be parcelable, I was wrong it doesn't work (even if I use ArrayList<Long>). Next I thought I'd just pass a long [], however I see no straight-forward conversion to go from ArrayList<Long> to long [] that intent.putExtra will accept. This was the solution I finally ended up with:

ArrayList handles= (ArrayList)result.get("fileHandles");
long [] handleArray = new long[handles.size()];
for (int i = 0; i < handles.size(); i++)
{
    handleArray[i] = Long.parseLong(handles.get(i).toString());
}

Obviously this seemed a little bit ridiculous to me, but every other conversion I tried seemed to complain for one reason or another. I've thought about re-thinking my serialization to have the problem taken care of before I get to this point, but I find it odd that passing ArrayList<Long> from activity to activity could be so difficult. Is there a more obvious solution I'm missing?

like image 545
Kevin DiTraglia Avatar asked Oct 07 '14 20:10

Kevin DiTraglia


People also ask

How to pass an ArrayList to another activity using intents in Android?

How to pass an arrayList to another activity using intents in Android? This example demonstrates how do I pass an arrayList to another activity using intends in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.

How to iterate over an ArrayList in Java?

You can iterate an ArrayList by using either forEach (Consumer), since Java 8, or for-each and other index-loops (while, do-while, for-index) Apart from that, iterator and listIterator can also be used to iterate over an ArrayList

What is the use of ArrayList in Java?

ArrayList is a part of the collection framework and is present in java.util package. It provides us with dynamic arrays in Java. The listIterator () method of java.util.ArrayList class is used to return a list iterator over the elements in this list (in a proper organized sequence).

How to pass custom object data to an intent in Android?

But Android has no custom object data type that can be passed directly through an intent as in primitive data types. So how do we able to pass such kind of custom object data? The answers is: “flatten the object into a Parcelable object, passing it into the intent, and rebuild the flatten object into the original object”.


2 Answers

You can use it as a Serializable extra. ArrayList is Serializable and Long extends Number which also implements Serializable:

// Put as Serializable
i.putExtra("handles", handles);

// Unfortunately you'll get an unsafe cast warning here, but it's safe to use
ArrayList<Long> handles = (ArrayList<Long>) i.getSerializableExtra("handles");    
like image 144
Kevin Coppock Avatar answered Oct 13 '22 01:10

Kevin Coppock


Two options: Use Parcelable or Serializable

in:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("handles", new FileHandles(handles));

out:

FileHandles handles = intent.getParcelableExtra("handles");

object:

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.List;

public class FileHandles implements Parcelable {

    private final List<Long> fileHandles;

    public FileHandles(List<Long> fileHandles) {
        this.fileHandles = fileHandles;
    }

    public FileHandles(Parcel in) {
        int size = in.readInt();
        long[] parcelFileHandles = new long[size];
        in.readLongArray(parcelFileHandles);
        this.fileHandles = toObjects(size, parcelFileHandles);
    }

    private List<Long> toObjects(int size, long[] parcelFileHandles) {
        List<Long> primitiveConv = new ArrayList<Long>();
        for (int i = 0; i < size; i++) {
            primitiveConv.add(parcelFileHandles[i]);
        }
        return primitiveConv;
    }

    public List<Long> asList() { // Prefer you didn't use this method & added domain login here, but stackoverflow can only teach so much..
        return fileHandles;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(fileHandles.size());
        dest.writeLongArray(toPrimitives(fileHandles));
    }

    private static long[] toPrimitives(List<Long> list) {
        return toPrimitives(list.toArray(new Long[list.size()]));
    }

    public static long[] toPrimitives(Long... objects) {
        long[] primitives = new long[objects.length];
        for (int i = 0; i < objects.length; i++)
            primitives[i] = objects[i];

        return primitives;
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        @Override
        public FileHandles createFromParcel(Parcel in) {
            return new FileHandles(in);
        }

        @Override
        public FileHandles[] newArray(int size) {
            return new FileHandles[size];
        }
    };
}

Serializable (forced to use ArrayList which implements Serializable (List does not)

in:

    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtra("handles", new ArrayList<Long>());

out:

    ArrayList handles = (ArrayList) intent.getSerializableExtra("handles");
like image 38
Blundell Avatar answered Oct 12 '22 23:10

Blundell