web-dev-qa-db-fra.com

Passer JSONObject à une autre activité

Je frappe une API externe qui renvoie des données JSON (nouveaux titres de DVD). Je suis capable d'analyser le JSON et de répertorier chaque titre de DVD et autres informations de DVD dans un ListView très bien. J'ai également pu configurer une méthode onListItemClick très bien pour les données primitives (chaîne de titre). J'ai fini par écrire quelque chose comme ça pour la méthode onListItemClick:

Juste pour noter, le productArray est une classe var qui est définie par une autre méthode qui contient un tableau de 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();
    }       

}

Le code ci-dessus fonctionne, mais je pense qu'il existe un meilleur moyen pour moi de transmettre des données à une autre activité. Je pensais que je serais en mesure de passer un JSONObject qui contient toutes les données d'un film DVD au lieu de définir chaque point de données individuellement.

J'ai essayé pendant une semaine et demie de comprendre comment utiliser Parcelable. J'ai essayé d'instancier un nouveau JSONObject jsonObj qui implémente Parcelable sans succès. J'ai continué à recevoir une erreur dans mon LogCat qui disait que l'objet n'était pas parcellable.

J'ai essayé de lire le Android et d'autres blogs, mais je n'ai pas pu appliquer leurs exemples à ce que je devais faire.

Toute aide serait très appréciée

37
Cavachon

Vous pouvez simplement encapsuler toutes les informations sur un film dans un objet Movie, qui implémente Parcelable.

Le code ressemblera à ci-dessus, mais au lieu de passer 6 extras différents, vous pouvez simplement passer un extra qui est le film.

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

Pour plus d'informations sur l'implémentation d'un objet Parcelable, voir Parcelable docs . Vous écrivez simplement chaque chaîne dans "writeToParcel" et lisez chaque chaîne dans "readFromParcel" dans le bon ordre.

14
Cheryl Simon

Vous pouvez simplement mettre un JSONObject entier sous forme de chaîne. Quelque chose comme ça:

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

Et puis dans le MovieProductActivity vous pourriez

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

191
ernazm

De l'activité actuelle

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

À partir de l'activité cible onCreate

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

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

} catch (JSONException e) {
   e.printStackTrace();
}
15
Philip Herbert

La réponse publiée ici par Cheryl Simon est tout à fait correcte, mais cela pourrait ne pas l'expliquer trop clairement pour quelqu'un qui est nouveau à Android ou Java. S'il vous plaît laissez-moi construire sur sa réponse.

La meilleure façon de le faire est d'utiliser l'interface Parcelable.

Déclarez une classe comme ci-dessous qui implémente Parcelable. Celui-ci utilise un accesseur et un mutateur qui n'est pas réellement nécessaire.

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

    }
}

L'étape suivante serait de créer une instance de cette classe (dans ce cas JSonArrayParser) et de la passer par le Bundle comme dans l'exemple ci-dessous.

// Il peut s'agir d'une activité, d'un fragment, d'un DialogFragment ou de toute classe qui utilise le type de bundle tel que 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");

La façon dont vous récupéreriez la valeur serait la suivante (j'ai utilisé le onCreate mais vous pouvez récupérer la valeur n'importe où):

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

Juste une remarque supplémentaire: vous pouvez le faire avec des constructeurs personnalisés, mais cette méthode a été déconseillée par Google. L'ancienne méthode obsolète (associée à la compatibilité de l'application v4 NON RECOMMANDÉ) serait:

private Fragment MyFragment;
MyFragment = new MyFragment(jsonArray)

J'espère que cette aide et clarifie certaines choses. L'interface Parcelable peut être utilisée avec n'importe quelle classe de données avec ou sans mutateurs et/ou accesseurs.

7
user2288580

Créez simplement un colis comme celui-ci:

public class Parcel implements Serializable {
private JSONObject obj;

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

public JSONObject getObj() {
    return obj;
}}

Et mettez dans le bundle:

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

Enfin, vous pouvez récupérer le JSONObject en utilisant:

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

Jetez un œil à gson. Il vous permet de sérialiser et de désérialiser les objets blob JSON sur des instances de classe entières.

1
Fergal Moran

Stockez-vous les informations dans une base de données? Si vous l'êtes, vous pouvez simplement transmettre l'ID du titre souhaité (via l'intention).

1
Pedro Loureiro