简体   繁体   中英

Passing JSONObject into another activity

I'm hitting an external API that's returning JSON data (new dvd titles). I'm able to parse out the JSON and list each dvd title and other dvd information into a ListView just fine. I was also able to setup an onListItemClick method just fine for primitive data (title string). I ended up writing something like so for the onListItemClick method:

Just to note, the productArray is a class var that's being set by another method that holds an array of JSONObjects.

protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    Intent i = new Intent(DvdListingActivity.this, MovieProductActivity.class);
    try {
        JSONObject jsonObj = productArray.getJSONObject(position);
        i.putExtra("mTitle", jsonObj.getJSONObject("Title").opt("val").toString());
        i.putExtra("mRelDate", jsonObj.getJSONObject("RelDate").opt("val").toString());
        i.putExtra("mDesc", jsonObj.getJSONObject("Desc").opt("val").toString());
        i.putExtra("mRating", jsonObj.getJSONObject("MPAA").getJSONObject("Rating").opt("val").toString());
        i.putExtra("mActors", jsonObj.getJSONObject("Actors").opt("val").toString());
        i.putExtra("mImage", jsonObj.getJSONObject("Image").opt("val").toString());
        startActivity(i);

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       

}

The above code all works, but I'm thinking there's GOTTA be a better way for me to pass in data to another Activity. I was thinking that I would be able to pass a JSONObject that contains all the data for a dvd movie instead of setting each data point individually.

I tried for a week and a half to figure out how to use Parcelable. I tried instantiating a new JSONObject jsonObj that implements Parcelable with no luck. I kept getting an error in my LogCat that said that the object was un-parcelable.

I've tried reading the Android developer site and other blogs, but I couldn't apply their examples to what I needed to do.

Any help would be much appreciated

You can simply put an entire JSONObject as a string. Something like this:

i.putString("product", jsonObj.toString);

And then in the MovieProductActivity you could

JSONObject jsonObj = new JSONObject(getIntent().getStringExtra("product"));

From Current Activity

Intent mIntent = new Intent(CurrentActivity.this, TargetActivity.class);
mIntent.putExtra("ITEM_EXTRA", json_object.toString());
startActivity(mIntent);

From Target Activity's onCreate

try {
   json_object = new JSONObject(getIntent().getStringExtra("ITEM_EXTRA"));

   Log.e(TAG, "Example Item: " + json_object.getString("KEY"));

} catch (JSONException e) {
   e.printStackTrace();
}

You can just encapsulate all of the information about a movie into a Movie object, which implements Parcelable .

The code will look similar to above, but instead of passing 6 different extras you can just pass one extra that is the movie.

Movie movie = new Movie();
movie.setTitle(jsonObj.getJSONObject("Title").opt("val").toString());
movie.setRelDat(jsonObj.getJSONObject("RelDate").opt("val").toString());
.
.
.
i.putExtra("movie", movie);

For information on implementing a Parcelable object, see Parcelable docs . You basically just write out each string in 'writeToParcel', and read in each string in 'readFromParcel' in the correct order.

The answer posted here by Cheryl Simon is completely correct however this might not explain it too clearly for someone who is new to android or java. Please let me build on her answer.

The best and cleanest way to do this is with the Parcelable interface.

Declare a class as below that implements Parcelable. This one uses an accessor and mutator which isn't actually necessary.

public class JSonArrayParser implements Parcelable {

    private JSONArray jsonArray;
    public JSonArrayParser() {}

    public JSonArrayParser(JSONArray jsonArray) {
        this.jsonArray = jsonArray;
    }

    public void setJsonArray(JSONArray jsonArray) {
        this.jsonArray = jsonArray;
    }

    public JSONArray getJsonArray() {
        return jsonArray;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {

    }
}

The next step would be to create an instance of that class (in this case JSonArrayParser) and pass it through the Bundle as in the example below.

//This could be an Activity, Fragment, DialogFragment or any class that uses the Bundle Type such as savedInstanceState.

jobItemsPopUp = new JobItemsPopUp();//This example uses a DialogFragment.
Bundle bundle = new Bundle();
JSonArrayParser jSonArrayParser = new JSonArrayParser(jsonArray);
bundle.putParcelable("jsonArray", jSonArrayParser);
jobItemsPopUp.setArguments(bundle);
jobItemsPopUp.show(getActivity().getSupportFragmentManager(), "JobItemsPopUp");

The the way your would retrieve the value would be as follows (I've used the onCreate but you can retrieve the value anywhere):

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        this.jsonArray = ((JSonArrayParser) getArguments().getParcelable("jsonArray")).getJsonArray();
    }
}

Just as an additional note: you can do this with custom constructors, but this method has been deprecated by Google. The old deprecated method (associated with app compat v4 NOT RECOMMENDED ) would be:

private Fragment MyFragment;
MyFragment = new MyFragment(jsonArray)

Hope this help and clears a few things up. The Parcelable interface can be used with any data class with or without mutators and/or accessors.

Just create a Parcel like this:

public class Parcel implements Serializable {
private JSONObject obj;

public Parcel(JSONObject obj) {
    this.obj = obj;
}

public JSONObject getObj() {
    return obj;
}}

And put into the bundle:

Parcel p = new Parcel(data);
    Bundle args = new Bundle();
    args.putSerializable("events", p);

Finally, you can get the JSONObject back using:

JSONObject obj = ((Parcel) ((Bundle) getArguments()).getSerializable("events")).getObj();

Are you storing the information in a DB? If you are, you can simply pass the ID of the desired title (via the intent).

Have a look at gson. It allows you to sereialise and deserialise JSON blobs to entire class instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM