简体   繁体   English

将JSONObject传递给另一个活动

[英]Passing JSONObject into another activity

I'm hitting an external API that's returning JSON data (new dvd titles). 我正在点击一个返回JSON数据的外部API(新的dvd标题)。 I'm able to parse out the JSON and list each dvd title and other dvd information into a ListView just fine. 我能够解析出JSON并将每个DVD标题和其他DVD信息列入ListView就好了。 I was also able to setup an onListItemClick method just fine for primitive data (title string). 我还能够为原始数据(标题字符串)设置一个onListItemClick方法。 I ended up writing something like so for the onListItemClick method: 我最终为onListItemClick方法写了类似的东西:

Just to note, the productArray is a class var that's being set by another method that holds an array of JSONObjects. 需要注意的是,productArray是一个类var,由另一个包含JSONObject数组的方法设置。

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. 上面的代码都有效,但我认为GOTTA是一种更好的方式让我将数据传递给另一个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. 我以为我能够传递一个包含dvd影片所有数据的JSONObject,而不是单独设置每个数据点。

I tried for a week and a half to figure out how to use Parcelable. 我尝试了一个半星期来弄清楚如何使用Parcelable。 I tried instantiating a new JSONObject jsonObj that implements Parcelable with no luck. 我尝试实例化一个新的JSONObject jsonObj,它实现了Parcelable而没有运气。 I kept getting an error in my LogCat that said that the object was un-parcelable. 我一直在我的LogCat中收到错误,该错误表示该对象是不可分割的。

I've tried reading the Android developer site and other blogs, but I couldn't apply their examples to what I needed to do. 我曾尝试阅读Android开发者网站和其他博客,但我无法将他们的示例应用到我需要做的事情上。

Any help would be much appreciated 任何帮助将非常感激

You can simply put an entire JSONObject as a string. 您可以简单地将整个JSONObject作为字符串。 Something like this: 像这样的东西:

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

And then in the MovieProductActivity you could 然后在MovieProductActivity你可以

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 来自Target Activity的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 . 您可以将有关电影的所有信息封装到Movie对象中,该对象实现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. 代码看起来与上面类似,但不是传递6个不同的附加内容,你可以只传递一个额外的电影。

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 . 有关实现Parcelable对象的信息,请参阅Parcelable docs You basically just write out each string in 'writeToParcel', and read in each string in 'readFromParcel' in the correct order. 你基本上只是在'writeToParcel'中写出每个字符串,并以正确的顺序读入'readFromParcel'中的每个字符串。

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. 谢丽尔西蒙在这里发布的答案是完全正确的,但对于刚接触android或java的人来说,这可能无法解释得太清楚。 Please let me build on her answer. 请让我以她的答案为基础。

The best and cleanest way to do this is with the Parcelable interface. 最好和最干净的方法是使用Parcelable接口。

Declare a class as below that implements Parcelable. 声明如下所示的实现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. 下一步是创建该类的实例(在本例中为JSonArrayParser)并将其传递给Bundle,如下例所示。

//This could be an Activity, Fragment, DialogFragment or any class that uses the Bundle Type such as savedInstanceState. //这可以是Activity,Fragment,DialogFragment或任何使用Bundle Type的类,例如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): 你将检索值的方式如下(我已经使用了onCreate但你可以在任何地方检索值):

@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. 另外请注意:您可以使用自定义构造函数执行此操作,但Google已弃用此方法。 The old deprecated method (associated with app compat v4 NOT RECOMMENDED ) would be: 旧的弃用方法(与app compat v4 NOT RECOMMENDED相关联)将是:

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. Parcelable接口可以与任何具有或不具有mutator和/或访问器的数据类一起使用。

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:

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). 如果是,您只需传递所需标题的ID(通过意图)。

Have a look at gson. 看看gson。 It allows you to sereialise and deserialise JSON blobs to entire class instances. 它允许您将JSON blob重新安排和反序列化为整个类实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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