Comment passer un objet D'une activité à une autre sur Android
j'essaie de travailler sur l'envoi d'un objet de mon client classe d'un Activity
et l'afficher dans un autre Activity
.
le code de La classe de la clientèle:
public class Customer {
private String firstName, lastName, Address;
int Age;
public Customer(String fname, String lname, int age, String address) {
firstName = fname;
lastName = lname;
Age = age;
Address = address;
}
public String printValues() {
String data = null;
data = "First Name :" + firstName + " Last Name :" + lastName
+ " Age : " + Age + " Address : " + Address;
return data;
}
}
je veux envoyer son objet d'un Activity
à un autre et ensuite afficher les données sur l'autre Activity
.
Comment puis-je y arriver?
30 réponses
une option pourrait être de laisser votre classe personnalisée implémenter l'interface Serializable
et ensuite vous pouvez passer des instances d'objet dans l'intention extra en utilisant la variante putExtra(Serializable..)
de la méthode Intent#putExtra()
.
Pseudo-code :
//To pass:
intent.putExtra("MyClass", obj);
// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Note: assurez-vous que chaque classe imbriquée de votre classe personnalisée principale a mis en œuvre une interface sérialisable pour éviter toute exception de sérialisation. Par exemple:
class MainClass implements Serializable {
public MainClass() {}
public static class ChildClass implements Serializable {
public ChildClass() {}
}
}
implémenter votre classe avec Serialisable. Supposons qu'il s'agisse de votre classe d'entités:
import java.io.Serializable;
@SuppressWarnings("serial") //With this annotation we are going to hide compiler warnings
public class Deneme implements Serializable {
public Deneme(double id, String name) {
this.id = id;
this.name = name;
}
public double getId() {
return id;
}
public void setId(double id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
private double id;
private String name;
}
nous envoyons l'objet appelé dene
de x activity à Y activity. Quelque part dans X de l'activité;
Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);
dans L'activité Y, nous obtenons l'objet.
Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");
C'est ça.
- global variables statiques n'est pas bon génie logiciel "151930920 pratique".
- Convertir les champs d'un objet en champs primitifs les types de données peuvent être un travail mouvementé .
- utiliser sérialisable est OK, mais ce n'est pas la performance-efficace sur la plate-forme Android.
- Partecelable is specifically conçu pour Android et vous devez l'utiliser. Voici un exemple simple: passer des objets personnalisés entre les activités Android
vous pouvez générer du code séparable pour votre classe en utilisant ce site .
tout en appelant une activité
Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);
dans toClass.java recevoir l'activité par
Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");
s'il vous Plaît assurez-vous que la clientèle de la classe implémente parcelable
public class Customer implements Parcelable {
private String firstName, lastName, address;
int age;
/* all your getter and setter methods */
public Customer(Parcel in ) {
readFromParcel( in );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public LeadData createFromParcel(Parcel in ) {
return new Customer( in );
}
public Customer[] newArray(int size) {
return new Customer[size];
}
};
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeString(address);
dest.writeInt(age);
}
private void readFromParcel(Parcel in ) {
firstName = in .readString();
lastName = in .readString();
address = in .readString();
age = in .readInt();
}
d'après mon expérience, il y a trois solutions principales, chacune avec ses inconvénients et ses avantages:
-
La Mise En Œuvre De Parcelable
-
La Mise En Œuvre De Serializable
-
utilisant une bibliothèque d'événements légère d'une sorte (par exemple, EventBus de Greenrobot ou Otto de Square)
séparable - rapide et Android standard, mais il a beaucoup de code boilerplate et nécessite des chaînes codées dur pour référence lors de tirer des valeurs sur l'intention (non fortement dactylographié).
sérialisable - près de zéro boilerplate, mais c'est l'approche la plus lente et nécessite également des chaînes codées dur lors de la traction valeurs sur l'intention (non fortement dactylographié).
Event Bus - boilerplate zéro, approche la plus rapide, et ne nécessite pas de chaînes à code dur, mais il nécessite une dépendance supplémentaire (bien que généralement léger, ~40 KB)
j'ai réalisé une comparaison détaillée autour de ces trois approches, y compris l'efficacité des repères.
utilisez gson pour convertir votre objet en JSON et passer par l'intention. Dans la nouvelle activité convertissez le JSON en objet.
dans votre build.gradle
, ajoutez ceci à vos dépendances
implementation 'com.google.code.gson:gson:2.8.4'
dans votre activité, convertissez l'objet en JSON-string:
Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);
dans votre activité de réception, convertissez la chaîne json en objet original:
Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);
Pour Kotlin c'est tout à fait le même
passer les données
val gson = Gson()
val intent = Intent(this, YourActivity::class.java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)
recevoir les données
val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)
vous pouvez aussi écrire les données de l'objet dans des chaînes temporaires et des entrées, et les passer à l'activité. Bien sûr, de cette façon, vous obtenez les données transportées, mais pas de l'objet lui-même.
mais si vous voulez juste les afficher, et ne pas utiliser l'objet dans une autre méthode ou quelque chose comme ça, cela devrait être suffisant. J'ai fait de la même façon à afficher uniquement les données d'un objet dans une autre activité.
String fName_temp = yourObject.getFname();
String lName_temp = yourObject.getLname();
String age_temp = yourObject.getAge();
String address_temp = yourObject.getAddress();
Intent i = new Intent(this, ToClass.class);
i.putExtra("fname", fName_temp);
i.putExtra("lname", lName_temp);
i.putExtra("age", age_temp);
i.putExtra("address", address_temp);
startActivity(i);
vous pouvez aussi les passer directement au lieu des Templiers, mais de cette façon, c'est plus clair, à mon avis. De plus, vous pouvez régler les temp ivars à null pour qu'ils soient nettoyés par le collecteur GarbageCollector plus tôt.
bonne chance!
sur une note latérale: outrepassez toString() au lieu d'écrire votre propre méthode d'impression.
comme mentionné dans les commentaires ci-dessous, voici comment vous obtenez vos données dans une autre activité:
String fName = getIntent().getExtras().getInt("fname");
j'ai trouvé une méthode simple et élégante:
- NO Parcellable
- NON Sérialisable
- PAS de Champ Statique
- Aucun Événement De Bus
Méthode 1
Code de la première activité:
final Object objSent = new Object();
final Bundle bundle = new Bundle();
bundle.putBinder("object_value", new ObjectWrapperForBinder(objSent));
startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
Log.d(TAG, "original object=" + objSent);
Code pour la deuxième activité:
final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
Log.d(TAG, "received object=" + objReceived);
vous trouverez objSent
et objReceived
ont le même hashCode
, donc ils sont identiques.
mais pourquoi passer un objet java de cette façon?
en fait, android binder va créer une référence JNI globale pour l'objet java et libérer cette référence JNI globale quand il n'y a pas de référence pour cet objet java. binder sauvegardera cette référence JNI globale en l'objet de Classeur.
*ATTENTION: cette méthode ne fonctionne que si les deux activités exécutées dans le même processus, autrement jeter ClassCastException au (ObjectWrapperForBinder)getIntent().getExtras ().getBinder ("object_value") *
class Objectfrapperforbinder defination
public class ObjectWrapperForBinder extends Binder {
private final Object mData;
public ObjectWrapperForBinder(Object data) {
mData = data;
}
public Object getData() {
return mData;
}
}
Méthode 2
- pour l'expéditeur,
- use sur mesure méthode native pour ajouter votre objet java à la table de référence globale JNI (via JNIEnv:: NewGlobalRef)
- mettez l'entier de retour (en fait, JNIEnv::NewGlobalRef return jobject, qui est un pointeur, nous pouvons le lancer à int en toute sécurité) à votre intention (via intention:: putExtra)
- pour le récepteur
- obtenir le nombre entier à partir de l'Intention(via Intention::getInt)
- utiliser la méthode native personnalisée pour restaurer your java object from JNI global reference table (via JNIEnv::NewLocalRef)
- supprimer l'élément du tableau de référence mondial JNI(via JNIEnv:: DeleteGlobalRef),
mais la méthode 2 a un problème petit mais sérieux, si le récepteur ne parvient pas à restaurer l'objet java (par exemple, une exception se produit avant de restaurer l'objet java, ou L'activité du récepteur n'existe pas du tout), alors l'objet java deviendra orphelin ou trou de mémoire, Méthode 1 n'ont pas ce problème, parce qu'android classeur de gérer cette exception
Méthode 3
pour invoquer l'objet java à distance, nous allons créer un contrat/interface de données pour décrire l'objet java, nous allons utiliser le fichier aidl
IDataContract.aidl
package com.example.objectwrapper;
interface IDataContract {
int func1(String arg1);
int func2(String arg1);
}
Code pour la première activité
final IDataContract objSent = new IDataContract.Stub() {
@Override
public int func2(String arg1) throws RemoteException {
// TODO Auto-generated method stub
Log.d(TAG, "func2:: arg1=" + arg1);
return 102;
}
@Override
public int func1(String arg1) throws RemoteException {
// TODO Auto-generated method stub
Log.d(TAG, "func1:: arg1=" + arg1);
return 101;
}
};
final Bundle bundle = new Bundle();
bundle.putBinder("object_value", objSent.asBinder());
startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
Log.d(TAG, "original object=" + objSent);
Code pour le second activité:
changer le android:processus d'attribut dans AndroidManifest.xml à un non-vide nom du processus pour s'assurer que la deuxième activité de l'exécuter dans un autre processus
final IDataContract objReceived = IDataContract.Stub.asInterface(getIntent().getExtras().getBinder("object_value"));
try {
Log.d(TAG, "received object=" + objReceived + ", func1()=" + objReceived.func1("test1") + ", func2()=" + objReceived.func2("test2"));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
de cette façon, nous pouvons passer une interface entre deux activités, même si elles s'exécutent dans un processus différent, et appeler la méthode d'interface à distance
Méthode 4
méthode 3 ne semble pas assez simple parce que nous devons mettre en place une interface aidl. Si vous voulez juste faire tâche simple et la valeur de retour de la méthode est inutile, nous pouvons utiliser android.OS.Messager
Code pour la première activité (expéditeur):
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int MSG_OP1 = 1;
public static final int MSG_OP2 = 2;
public static final String EXTRA_MESSENGER = "messenger";
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.e(TAG, "handleMessage:: msg=" + msg);
switch (msg.what) {
case MSG_OP1:
break;
case MSG_OP2:
break;
default:
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startActivity(new Intent(this, SecondActivity.class).putExtra(EXTRA_MESSENGER, new Messenger(mHandler)));
}
}
Code pour la deuxième activité (récepteur ):
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
final Messenger messenger = getIntent().getParcelableExtra(MainActivity.EXTRA_MESSENGER);
try {
messenger.send(Message.obtain(null, MainActivity.MSG_OP1, 101, 1001, "10001"));
messenger.send(Message.obtain(null, MainActivity.MSG_OP2, 102, 1002, "10002"));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
tout le Messager.send s'exécute dans un gestionnaire de manière asynchrone et séquentielle.
en fait, androïde.OS.Messenger est aussi une interface aidl, si vous avez le code source android, vous pouvez trouver un fichier nommé IMessenger.aidl
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
j'ai fait une classe d'aide singleton qui contient des objets temporaires.
public class IntentHelper {
private static IntentHelper _instance;
private Hashtable<String, Object> _hash;
private IntentHelper() {
_hash = new Hashtable<String, Object>();
}
private static IntentHelper getInstance() {
if(_instance==null) {
_instance = new IntentHelper();
}
return _instance;
}
public static void addObjectForKey(Object object, String key) {
getInstance()._hash.put(key, object);
}
public static Object getObjectForKey(String key) {
IntentHelper helper = getInstance();
Object data = helper._hash.get(key);
helper._hash.remove(key);
helper = null;
return data;
}
}
au lieu de mettre vos objets dans L'intention, utilisez IntentHelper:
IntentHelper.addObjectForKey(obj, "key");
dans votre nouvelle activité, vous pouvez obtenir l'objet:
Object obj = (Object) IntentHelper.getObjectForKey("key");
garder à l'esprit qu'une fois chargé, l'objet est supprimé pour éviter les références inutiles.
il y a plusieurs façons d'accéder à des variables ou à des objets dans d'autres classes ou activités.
A. Base De Données
B. préférences partagées.
C. sérialisation des objets.
D. Une classe qui peut contenir des données communes peut être nommée comme utilitaire commun. Il dépend de vous.
E. transmission des données par Intents et par L'Interface séparable.
cela dépend sur les besoins de votre projet.
A. Base De Données
SQLite est une base de données open source qui est intégré dans Android. SQLite soutient les traits de base de données relationnelles standard comme la syntaxe de SQL, les transactions et les déclarations préparées.
B. préférences partagées
"Supposons que vous souhaitez stocker le nom d'utilisateur. Donc, il y aura maintenant deux choses, une clé nom d'utilisateur, valeur valeur.
comment conserver
// Create object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//Now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//Put your value
editor.putString("userName", "stackoverlow");
//Commits your edits
editor.commit();
en utilisant putString(), putBoolean(), putInt(), putFloat(), et putLong() vous pouvez sauvegarder votre dtatype désiré.
Comment extraire les
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
http://developer.android.com/reference/android/content/SharedPreferences.html
C. sérialisation d'un Objet
Objet serlization est utilisé si l'on veux enregistrer un état de l'objet à envoyer sur un réseau ou vous pouvez l'utiliser pour votre usage.
utilisez Java beans et stocker en elle comme l'un de ses champs et d'utiliser getters et setter pour cela.
JavaBeans sont des classes Java qui ont des propriétés. Pensez propriétés comme variables d'instance privée. Depuis qu'ils sont privés, la seule façon ils peuvent être accessibles à partir de l'extérieur de leur classe est par des méthodes dans la classe. Les méthodes qui changent la valeur d'une propriété sont appelées méthodes setter, et les méthodes qui récupèrent la valeur d'une propriété sont appelées méthodes getter.
public class VariableStorage implements Serializable {
private String inString;
public String getInString() {
return inString;
}
public void setInString(String inString) {
this.inString = inString;
}
}
définissez la variable dans votre méthode de messagerie en utilisant
VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
puis utilisez la sérialisation d'objet pour sérialiser cet objet et dans votre autre classe désérialiser cet objet.
Dans la sérialisation d'un objet peut être représenté comme une séquence d'octets qui comprend les données de l'objet ainsi que des informations sur le type de l'objet et les types de données stockées dans l'objet.
Après un objet sérialisé a été écrit dans un fichier, il peut être lu à partir du fichier et désérialisé. C'est le type de l'information et de octets qui représentent l'objet et ses données peuvent être utilisées pour recréer l'objet en mémoire.
si vous voulez tutoriel pour cela se référer à:
-
la Sérialisation en Java (blog)
-
obtenir la variable dans les autres classes (débordement de la cheminée)
D. CommonUtilities
vous pouvez faire une classe par vous-même qui peut contenir des données communes dont vous avez fréquemment besoin dans votre projet.
échantillon
public class CommonUtilities {
public static String className = "CommonUtilities";
}
E. transmission de données par les intentions
S'il vous plaît se référer au tutoriel Android-Données de parcelle à passer entre Activités utilisant les classes séparables pour cette option de transmission de données.
la meilleure façon est d'avoir une classe (appelez le contrôle) dans votre application qui tiendra une variable statique de type 'client' (dans votre cas). Initialisez la variable dans votre activité A.
par exemple:
Control.Customer = CustomerClass;
ensuite, allez à L'activité B et rapportez-la de la classe de contrôle. N'oubliez pas d'attribuer un null après avoir utilisé la variable, sinon la mémoire sera gaspillée.
public class MyClass implements Serializable{
Here is your instance variable
}
Maintenant vous voulez passer l'objet de cette classe dans startActivity. Utilisez simplement ceci:
Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);
cela fonctionne ici parce que MyClass met en œuvre Serializable
.
créez votre propre classe Customer
comme suit:
import import java.io.Serializable;
public class Customer implements Serializable
{
private String name;
private String city;
public Customer()
{
}
public Customer(String name, String city)
{
this.name= name;
this.city=city;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city= city;
}
}
dans votre onCreate()
méthode
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top);
Customer cust=new Customer();
cust.setName("abc");
cust.setCity("xyz");
Intent intent=new Intent(abc.this,xyz.class);
intent.putExtra("bundle",cust);
startActivity(intent);
}
dans la classe xyz activity
vous devez utiliser le code suivant:
Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
si vous choisissez d'utiliser la façon dont Samuh décrit, rappelez-vous que seules les valeurs primitives peuvent être envoyées. Cela signifie que les valeurs qui sont parcable. Donc, si votre objet contient des objets complexes elles ne pourront pas suivre. Par exemple, les variables comme Bitmap, HashMap etc... Ces sont difficiles à passer par l'intention.
en général, je vous conseille d'envoyer seulement des types de données primitifs comme extras, comme String, int, boolean etc. Dans votre cas, ce serait: String fname
, String lname
, int age
, et String address
.
Mon avis: des objets Plus complexes sont mieux partagés par la mise en œuvre d'un ContentProvider , SDCard , etc. Il est également possible d'utiliser une variable statique , mais cela peut rapidement conduire à un code sujet à erreur...
mais encore une fois, c'est juste mon opinion subjective.
j'utilise parcelable pour envoyer des données d'une activité à une autre activité. Voici mon code qui fonctionne très bien dans mon projet.
public class Channel implements Serializable, Parcelable {
/** */
private static final long serialVersionUID = 4861597073026532544L;
private String cid;
private String uniqueID;
private String name;
private String logo;
private String thumb;
/**
* @return The cid
*/
public String getCid() {
return cid;
}
/**
* @param cid
* The cid to set
*/
public void setCid(String cid) {
this.cid = cid;
}
/**
* @return The uniqueID
*/
public String getUniqueID() {
return uniqueID;
}
/**
* @param uniqueID
* The uniqueID to set
*/
public void setUniqueID(String uniqueID) {
this.uniqueID = uniqueID;
}
/**
* @return The name
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the logo
*/
public String getLogo() {
return logo;
}
/**
* @param logo
* The logo to set
*/
public void setLogo(String logo) {
this.logo = logo;
}
/**
* @return the thumb
*/
public String getThumb() {
return thumb;
}
/**
* @param thumb
* The thumb to set
*/
public void setThumb(String thumb) {
this.thumb = thumb;
}
public Channel(Parcel in) {
super();
readFromParcel(in);
}
public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
public Channel createFromParcel(Parcel in) {
return new Channel(in);
}
public Channel[] newArray(int size) {
return new Channel[size];
}
};
public void readFromParcel(Parcel in) {
String[] result = new String[5];
in.readStringArray(result);
this.cid = result[0];
this.uniqueID = result[1];
this.name = result[2];
this.logo = result[3];
this.thumb = result[4];
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this.cid, this.uniqueID,
this.name, this.logo, this.thumb});
}
}
en activityA utilisez-le comme ceci:
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);
dans ActivityB utilisez-le comme ceci pour obtenir des données:
Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");
Vous pouvez essayer d'utiliser cette classe. La limitation est qu'il ne peut pas être utilisé en dehors d'un processus.
une activité:
final Object obj1 = new Object();
final Intent in = new Intent();
in.putExtra(EXTRA_TEST, new Sharable(obj1));
autre activité:
final Sharable s = in.getExtras().getParcelable(EXTRA_TEST);
final Object obj2 = s.obj();
public final class Sharable implements Parcelable {
private Object mObject;
public static final Parcelable.Creator < Sharable > CREATOR = new Parcelable.Creator < Sharable > () {
public Sharable createFromParcel(Parcel in ) {
return new Sharable( in );
}
@Override
public Sharable[] newArray(int size) {
return new Sharable[size];
}
};
public Sharable(final Object obj) {
mObject = obj;
}
public Sharable(Parcel in ) {
readFromParcel( in );
}
Object obj() {
return mObject;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel out, int flags) {
final long val = SystemClock.elapsedRealtime();
out.writeLong(val);
put(val, mObject);
}
private void readFromParcel(final Parcel in ) {
final long val = in .readLong();
mObject = get(val);
}
/////
private static final HashMap < Long, Object > sSharableMap = new HashMap < Long, Object > (3);
synchronized private static void put(long key, final Object obj) {
sSharableMap.put(key, obj);
}
synchronized private static Object get(long key) {
return sSharableMap.remove(key);
}
}
Crète une classe comme la classe de haricots et mettre en œuvre l'interface Serializable
. Ensuite, nous pouvons passer par la méthode intent
, par exemple:
intent.putExtra("class", BeanClass);
puis l'obtenir de l'autre activité, par exemple:
BeanClass cb = intent.getSerializableExtra("class");
créer deux méthodes dans votre classe personnalisée comme ceci
public class Qabir {
private int age;
private String name;
Qabir(){
}
Qabir(int age,String name){
this.age=age; this.name=name;
}
// method for sending object
public String toJSON(){
return "{age:" + age + ",name:\"" +name +"\"}";
}
// method for get back original object
public void initilizeWithJSONString(String jsonString){
JSONObject json;
try {
json =new JSONObject(jsonString );
age=json.getInt("age");
name=json.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
maintenant dans votre activité d'expéditeur faites comme ceci
Qabir q= new Qabir(22,"KQ");
Intent in=new Intent(this,SubActivity.class);
in.putExtra("obj", q.toJSON());
startActivity( in);
et dans votre activité de récepteur
Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));
lancer une autre activité à partir de cette activité et passer les paramètres via L'objet Bundle
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);
retrieve data on another activity (your activity)
String s = getIntent().getStringExtra("USER_NAME");
c'est ok pour le type de données simple. Mais si vous voulez transmettre des données complexes entre deux activités. U besoin de sérialiser en premier.
ici, nous avons le modèle employé
class Employee{
private String empId;
private int age;
print Double salary;
getters...
setters...
}
vous pouvez utiliser Gson lib fourni par google pour sérialiser les données complexes comme ceci
String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);
Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
Gson gson = new Gson();
Type type = new TypeToken<Employee>() {
}.getType();
Employee selectedEmp = gson.fromJson(empStr, type);
cette question est également abordée dans une autre question sur le débordement des cheminées. S'il vous plaît jeter un oeil à une solution à passer des données par l'intention en utilisant Serialisable . Le point principal est d'utiliser Bundle
objet qui stocke les données nécessaires à l'intérieur de Intent
.
Bundle bundle = new Bundle();
bundle.putSerializable(key1, value1);
bundle.putSerializable(key2, value2);
bundle.putSerializable(key3, value3);
intent.putExtras(bundle);
pour extraire les valeurs:
Bundle bundle = new Bundle();
for (String key : bundle.keySet()) {
value = bundle.getSerializable(key));
}
avantage de Serializable
est sa simplicité. Cependant, vous devez envisagez d'utiliser la méthode Parcelable
si vous avez besoin de nombreuses données à transférer, parce que Parcelable
est spécifiquement conçu pour Android et il est plus efficace que Serializable
. Vous pouvez créer Parcelable
classe en utilisant:
- un outil en ligne - parcelabler
- un plugin pour Android Studio - générateur de code mobile Android
Oui, utiliser un objet statique est de loin la façon la plus facile de le faire avec des objets personnalisés non-sérialisables.
les objets D'Activité Android peuvent être détruits et reconstitués. Donc, vous aurez besoin d'utiliser une autre approche pour regarder eux - ou tout objet qu'ils créent !!! - jusqu'. C'est-à-dire que vous pourriez passer pour une référence de classe statique, mais alors le handle d'objet (Java appelle ces "références", comme le fait SmallTalk; mais ce ne sont pas des références au sens de C ou assembly) sera peut-être invalide plus tard parce qu'une" fonctionnalité " D'OE Android est toute activité peut être annihilée et reconstituée tard.
la question originale demandé" Comment passer objet d'une activité à une autre dans Android " et personne n'a répondu que. Bien sûr, vous pouvez sérialiser (sérialisable, séparable, vers/depuis JSON) et passer une copie des données de l'objet et un nouvel objet ayant les mêmes données pourrait être créé; mais il n'aura pas les mêmes références/poignées. Aussi, beaucoup d'autres ont mentionné que vous pouvez stocker la référence dans un magasin statique. Et ça va marcher à moins que Android décide d'ondestroyer votre Activité.
donc, pour vraiment résoudre la question originale, vous auriez besoin d'une recherche statique plus chaque objet mettra à jour sa référence quand/si elle est recréée. Par exemple: chaque activité Android se reliserait si son onCreate est appelé. Vous pouvez également voir comment certaines personnes utilisent la liste des tâches pour rechercher une activité par son nom. (système est en train de détruire temporairement cette instance de l'activité pour économiser de l'espace..getRunningTasks, la liste des tâches est effectivement une liste spécialisée des l'exemple d'objet le plus récent de chaque activité).
pour référence:
arrêté: "L'activité est complètement masqué par une autre activité (l'activité est maintenant dans le "fond"). Une activité arrêtée est également toujours en vie (l'objet D'activité est conservé en mémoire , il conserve toutes les informations sur l'état et les membres, mais n'est pas attaché au gestionnaire de fenêtres). Cependant, il n'est plus visible pour l'utilisateur et il peuvent être tués par le système lorsque la mémoire est nécessaire ailleurs."
onDestroy "le système est temporairement détruire cette instance de l'activité pour économiser de l'espace."
ainsi, le Bus de messages est une solution réalisable. Il fondamentalement des "plates". Plutôt que d'essayer d'avoir des références à des objets, alors vous réorganisez votre design pour utiliser le MessagePassing au lieu du SequentialCode. Exponentiellement plus difficile à déboguer; mais il vous permet de ne tenez pas compte de ce genre de compréhension de L'environnement opérationnel. En effet, chaque accès de méthode objet est inversé de sorte que l'appelant affiche un Message et l'objet lui-même définit un gestionnaire pour ce message. Beaucoup plus de code, mais peut le rendre robuste avec les restrictions OE Android.
si tout ce que vous voulez est L'activité supérieure (chose typique dans les applications Android en raison du "contexte" étant nécessaire partout), alors vous pouvez juste avoir chaque activité se répertorie comme "haut" dans l'espace statique mondial chaque fois que son onResume est appelé. Alors votre AlertDialog ou n'importe quoi qui a besoin d'un contexte peut simplement l'attraper de là. Aussi, c'est un peu malchanceux d'utiliser un global mais peut simplifier passer un contexte de haut en bas partout et, pour sûr, quand vous utilisez un MessageBus alors il est global de toute façon.
-
je sais que la statique est mauvaise, mais il semble que nous sommes forcés de l'utiliser ici. Le problème avec parceables / seriazables est que les deux activités ont des instances dupliquées du même objet = perte de mémoire et CPU.
public class IntentMailBox { static Queue<Object> content = new LinkedList<Object>(); }
activité appelant
IntentMailBox.content.add(level);
Intent intent = new Intent(LevelsActivity.this, LevelActivity.class);
startActivity(intent);
activité appelée (notez que onCreate () et onResume () peut être appelé plusieurs fois lorsque le système détruit et recrée des activités)
if (IntentMailBox.content.size()>0)
level = (Level) IntentMailBox.content.poll();
else
// Here you reload what you have saved in onPause()
-
une Autre façon est de déclarer un champ statique de la classe que vous souhaitez passer dans la classe. Il servira uniquement à cette fin. N'oubliez pas qu'il peut être nul dans onCreate, parce que votre paquet app a été déchargé de la mémoire par le système et rechargé plus tard.
-
en gardant à l'esprit que vous avez encore besoin de gérer le cycle de vie de l'activité, vous pouvez vouloir écrire toutes les données directement aux préférences partagées, douloureux avec des structures de données complexes comme il est.
ci-dessus réponses presque toutes correctes, mais pour ceux qui ne sous-estime pas et ces réponses Android a powerfull classe intention avec l'aide de celle-ci, vous partagez des données entre non seulement l'activité, mais d'autres composants D'Android (Récepteur de diffusion, servises pour le contenu de fournir que nous utilisons ContetnResolver classe aucune intention). Dans votre activité vous construisez intention
Intent intent = new Intent(context,SomeActivity.class);
intent.putExtra("key",value);
startActivity(intent);
dans votre activité de recul vous avez
public class SomeActivity extends AppCompactActivity {
public void onCreate(...){
...
SomeObject someObject = getIntent().getExtras().getParceable("key");
}
}
You doivent mettre en œuvre L'interface Parceable ou sérialisable sur votre objet afin de partager entre les activités. Il est difficile de mettre en œuvre Parcealbe plutôt que Serialisable interface sur l'objet c'est pourquoi android a plugin spécialement pour cela.Téléchargez-le et utilisez-le
je me suis toujours demandé pourquoi cela ne peut pas être aussi simple que d'appeler une méthode de l'autre activité. J'ai récemment écrit une bibliothèque utilitaire qui le rend presque aussi simple que cela. Vous pouvez le consulter ici ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).
GNLauncher rend l'envoi d'objets/données à une activité à partir d'une autre activité etc aussi facile que l'appel d'une fonction dans l'activité avec le données requises comme paramètres. Il introduit la sécurité de type et supprime tous les hastles de devoir serialize, attachant à l'intention en utilisant des clés de chaîne et de défaire la même à l'autre extrémité.
Utilisation
définissez une interface avec les méthodes que vous souhaitez utiliser pour lancer l'activité.
public interface IPayload {
public void sayHello(String name, int age);
}
implémenter l'interface ci-dessus sur l'activité à lancer. Prévenez également GNLauncher lorsque l'activité est prête.
public class Activity_1 extends Activity implements IPayload {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Notify GNLauncher when the Activity is ready.
GNLauncher.get().ping(this);
}
@Override
public void sayHello(String name, int age) {
Log.d("gnlib_test", "Hello " + name + "! \nYour age is: " + age);
}
}
Dans l'autre Activité, obtenir un proxy à l'Activité ci-dessus et appeler n'importe quelle méthode avec les paramètres souhaités.
public class Activity_2 extends Activity {
public void onClick(View v) {
((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
}
}
La première activité sera lancée et la méthode appelée avec les paramètres requis.
prérequis
consultez https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites pour plus d'informations sur la façon d'ajouter les dépendances.
passer l'objet d'une activité à une autre.
(1) activité de la source
Intent ii = new Intent(examreport_select.this,
BarChartActivity.class);
ii.putExtra("IntentExamResultDetail",
(Serializable) your List<ArraList<String>> object here);
startActivity(ii);
(2) destination acitivité
List<ArrayList<String>> aa = (List<ArrayList<String>>) getIntent()
.getSerializableExtra("IntentExamResultDetail");
j'ai utilisé pour mettre objet avec Pacelable ou Serialisable à transférer, mais chaque fois que j'ajoute d'autres variables à Objet(model), je dois tout enregistrer. C'est tellement nconvenient.
il est très facile de transférer un objet entre des activités ou des fragments.
nous pouvons passer l'objet d'une activité à une autre:
SupplierDetails poSuppliersDetails = new SupplierDetails();
à l'Intérieur poSuppliersDetails
nous avons des valeurs. Maintenant, j'envoie cet objet à l'activité cible:
Intent iPODetails = new Intent(ActivityOne.this, ActivityTwo.class);
iPODetails.putExtra("poSuppliersDetails", poSuppliersDetails);
Comment obtenir ce ACtivityTwo:
private SupplierDetails supplierDetails;
supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");
passer D'une activité à une autre:
startActivity(new Intent(getBaseContext(),GetActivity.class).putExtra("passingkey","passingvalue"));
Obtenir les valeurs:
String myvalue= getIntent().getExtras("passingkey");
Bonjour à tous, je vois beaucoup de bonnes options, mais je me demandais pourquoi la Liaison n'a pas été utilisé?
passer une référence à un objet me semble juste plus efficace que de sérialiser et de desteriliser des objets, mais je n'ai pas fait de plongée profonde pour voir si c'est ce qui se passe dans les coulisses.
créer un classeur est assez simple...
public class MyBinder extends Binder {
private Object myObject;
public MyBinder(Object object) {
myObject = object;
}
public Object getObject() {
return myObject;
}
}
et la création du parcelable pour l'utiliser n'est pas mauvais de l'éther.
public class MyParcelable implements Parcelable {
private Object myObject;
public MyParcelable() {
}
public MyParcelable(Parcel parcel) {
myObject = ((MyBinder)parcel.readStrongBinder()).getObject();
}
public void setObject(Object object) {
myObject = object;
}
public Object getObject() {
return myObject;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeStrongBinder(new MyBinder(myObject));
}
public int describeContents() {
return myObject == null ? 0 : 1;
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel parcel) {
return new MyParcelable(parcel);
}
public MyParcelable[] newArray(int length) {
return new MyParcelable[length];
}
};
}
Cette logique est vraiment cool, parce que vous êtes réellement en passant une référence d'activité.
je conseillerais de vérifier pour nulls et si l'instanceof Binder est mon relieur!
et de mettre en œuvre ce que vous venez...
Envoyer
Object myObject = "some object";
MyParcelable myParcelable = new MyParcelable();
myParcelable.setObject(myObject);
intent.putExtra("MyParcelable", myParcelable);
récupérer
myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();
Heck quelqu'un pourrait devenir fou et faire de ce crétin un vrai Générique.