41

我正在使用一个返回 JSON 数据(新的 dvd 标题)的外部 API。我能够解析出 JSON 并将每个 dvd 标题和其他 dvd 信息列出到 ListView 中就好了。我还能够为原始数据(标题字符串)设置一个 onListItemClick 方法。我最终为 onListItemClick 方法编写了类似的内容:

请注意,productArray 是一个类 var,它由另一个方法设置,该方法包含一个 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();
    }       

}

上面的代码一切正常,但我认为有更好的方法让我将数据传递给另一个活动。我在想我将能够传递一个包含 dvd 电影的所有数据的 JSONObject,而不是单独设置每个数据点。

我尝试了一个半星期来弄清楚如何使用 Parcelable。我尝试实例化一个新的 JSONObject jsonObj,它实现了 Parcelable 但没有运气。我在我的 LogCat 中不断收到一个错误,指出该对象不可打包。

我已经尝试阅读 Android 开发者网站和其他博客,但我无法将他们的示例应用于我需要做的事情。

任何帮助将非常感激

4

7 回答 7

202

您可以简单地将整个 JSONObject 作为字符串。像这样的东西:

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

然后在MovieProductActivity你可以

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

于 2011-03-14T15:04:07.337 回答
24

从当前活动

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

从目标活动的 onCreate

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

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

} catch (JSONException e) {
   e.printStackTrace();
}
于 2016-01-16T22:43:11.483 回答
14

您可以将有关电影的所有信息封装到一个Movie对象中,该对象实现Parcelable.

代码看起来与上面类似,但不是传递 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);

有关实现 Parcelable 对象的信息,请参阅Parcelable 文档。你基本上只是写出'writeToParcel'中的每个字符串,并以正确的顺序读入'readFromParcel'中的每个字符串。

于 2011-02-22T18:41:28.057 回答
7

Cheryl Simon 在此处发布的答案是完全正确的,但是对于不熟悉 android 或 java 的人来说,这可能无法解释得太清楚。请让我以她的回答为基础。

最好和最干净的方法是使用 Parcelable 界面。

如下声明一个实现 Parcelable 的类。这个使用了实际上没有必要的访问器和修改器。

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) {

    }
}

下一步是创建该类的实例(在本例中为 JSonArrayParser)并将其传递给 Bundle,如下例所示。

//这可以是 Activity、Fragment、DialogFragment 或任何使用 Bundle 类型的类,例如 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");

您检索值的方式如下(我使用了 onCreate 但您可以在任何地方检索值):

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

作为附加说明:您可以使用自定义构造函数来执行此操作,但此方法已被 Google 弃用。不推荐使用的旧方法(与 app compat v4 NOT RECOMMENDED相关联)将是:

private Fragment MyFragment;
MyFragment = new MyFragment(jsonArray)

希望这有助于并清除一些事情。Parcelable 接口可以与任何带有或不带有修改器和/或访问器的数据类一起使用。

于 2014-09-17T06:02:52.487 回答
1

您是否将信息存储在数据库中?如果是,您可以简单地传递所需标题的 ID(通过意图)。

于 2011-02-22T18:54:51.263 回答
1

看看gson。它允许您将 JSON blob 序列化和反序列化到整个类实例。

于 2011-02-22T19:06:36.660 回答
1

只需像这样创建一个包裹:

public class Parcel implements Serializable {
private JSONObject obj;

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

public JSONObject getObj() {
    return obj;
}}

并放入包中:

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

最后,您可以使用以下方法取回 JSONObject:

JSONObject obj = ((Parcel) ((Bundle) getArguments()).getSerializable("events")).getObj();
于 2016-12-31T00:46:57.633 回答