it-swarm.com.de

So übergeben Sie ein Objekt unter Android von einer Aktivität an eine andere

Ich versuche, ein Objekt meiner customer class aus einer Activity zu senden und es in einer anderen Activity anzuzeigen.

Der Code für die Kundenklasse:

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;
    }
}

Ich möchte sein Objekt von einer Activity an eine andere senden und dann die Daten auf der anderen Activity anzeigen.

Wie kann ich das erreichen?

662
kaibuki

Eine Option könnte sein, dass Ihre benutzerdefinierte Klasse die Serializable-Schnittstelle implementiert, und Sie können dann Objektinstanzen mit der putExtra(Serializable..)-Variante der Intent#putExtra()-Methode im Intents extra übergeben.

Pseudocode :

//To pass:
intent.putExtra("MyClass", obj);

// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");

Anmerkung: Stellen Sie sicher, dass für jede geschachtelte Klasse Ihrer benutzerdefinierten Hauptklasse die serialisierbare Schnittstelle implementiert ist, um Serialisierungsausnahmen zu vermeiden. Zum Beispiel: 

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}
780
Samuh

Implementieren Sie Ihre Klasse mit Serializable. Nehmen wir an, dies ist Ihre Entitätsklasse:

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;
}

Wir senden das Objekt dene von X-Aktivität an Y-Aktivität. Irgendwo in X-Aktivität;

Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);

In Y-Aktivität bekommen wir das Objekt.

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");

Das ist es.

278
Mustafa Güven
  • Die Verwendung von globalen statischen Variablen ist keine gute Softwareentwicklung Übung.
  • Felder eines Objekts in Grundelemente umwandeln Datentypen können ein hektischer Job sein.
  • Die Verwendung von serialisierbar ist OK, aber nicht leistungsfähig auf der Plattform Android.
  • Parcelable is specific wurde für Android entwickelt und sollte verwendet werden. Hier ist ein einfaches Beispiel: Übergeben von benutzerdefinierten Objekten zwischen Android Aktivitäten

Mit diesem site können Sie Paketcode für Ihre Klasse generieren.

116
SohailAziz

Beim Aufrufen einer Aktivität 

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);

In toClass.Java erhalten Sie die Aktivität per 

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

Bitte stellen Sie sicher, dass die Kundenklasse Parcelable implementiert

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();
    }
90
Ads

Nach meiner Erfahrung gibt es drei Hauptlösungen mit jeweils ihren Nachteilen und Vorteilen:

  1. Parcelable implementieren

  2. Serializable implementieren

  3. Verwenden einer leichten Event-Bus-Bibliothek (z. B. EventBus von Greenrobot oder Otto von Square)

Parcelable - Schneller und Android-Standard, aber es verfügt über eine Menge Boilerplate-Code und erfordert hart codierte Zeichenketten als Referenz, wenn Werte aus dem Intent gezogen werden (nicht stark typisiert).

Serializable - nahe an der Nullpunkt-Boilerplate, aber es ist der langsamste Ansatz und erfordert auch hartcodierte Zeichenfolgen, wenn Werte aus dem Intent gezogen werden (nicht stark typisiert).

Event Bus - Zero Boilerplate, schnellste Annäherung und erfordert keine hartcodierten Zeichenfolgen, erfordert jedoch eine zusätzliche Abhängigkeit (obwohl in der Regel leicht, ~ 40 KB)

Ich habe einen sehr detaillierten Vergleich zu diesen drei Ansätzen veröffentlicht, einschließlich Effizienz-Benchmarks.

79

Verwenden Sie gson , um Ihr Objekt in JSON zu konvertieren und durch Absicht zu übergeben. Konvertieren Sie in der neuen Aktivität die JSON in ein Objekt.

Fügen Sie dies in Ihrem build.gradle zu Ihren Abhängigkeiten hinzu

implementation 'com.google.code.gson:gson:2.8.4'

Konvertieren Sie in Ihrer Aktivität das Objekt in json-string:

Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);

Konvertieren Sie in Ihrer Empfangsaktivität den Json-String zurück in das ursprüngliche Objekt:

Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);

Für Kotlin ist es dasselbe

Übergeben Sie die Daten

val gson = Gson()
val intent = Intent(this, YourActivity::class.Java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)

Erhalten Sie die Daten

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.Java)
76
khalid

Sie können die Daten des Objekts auch in temporäre Strings und Ints schreiben und an die Aktivität übergeben. Auf diese Weise erhalten Sie zwar die Daten transportiert, nicht aber das Objekt selbst.

Wenn Sie sie jedoch nur anzeigen möchten und das Objekt nicht in einer anderen Methode oder in ähnlicher Weise verwenden möchten, sollte dies ausreichend sein. Ich habe es auf dieselbe Weise getan, nur Daten von einem Objekt in einer anderen Aktivität anzuzeigen.

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

Sie können sie auch direkt an Stelle der temporären Efeure übergeben, aber auf diese Weise wird dies meiner Meinung nach klarer. Außerdem können Sie die temporären Ivars auf null setzen, damit sie früher vom GarbageCollector bereinigt werden.

Viel Glück!

Nebenbei bemerkt: überschreiben Sie toString (), anstatt Ihre eigene Druckmethode zu schreiben.

Wie in den Kommentaren unten erwähnt, erhalten Sie so Ihre Daten in einer anderen Aktivität zurück:

String fName = getIntent().getExtras().getInt("fname");
38
MJB

Ich habe eine einfache und elegante Methode gefunden:

  • KEIN Paketgut
  • NEIN serialisierbar
  • KEIN statisches Feld
  • Kein Event Bus

Methode 1

Code für die erste Aktivität:

    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 für die zweite Aktivität:

    final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
    Log.d(TAG, "received object=" + objReceived);

sie werden feststellen, dass objSent & objReceived die gleiche hashCode hat, also sind sie identisch.

Aber warum können wir ein Java-Objekt auf diese Weise übergeben?

Tatsächlich erstellt der Android-Binder eine globale JNI-Referenz für Java-Objekte und gibt diese globale JNI-Referenz frei, wenn keine Referenz für dieses Java-Objekt vorhanden ist. binder speichert diese globale JNI-Referenz im Binder-Objekt.

* ACHTUNG: Diese Methode funktioniert NUR, wenn die beiden Aktivitäten nicht im selben Prozess ausgeführt werden. Anderenfalls werfen Sie ClassCastException um (ObjectWrapperForBinder) getIntent (). GetExtras (). GetBinder ("object_value") *

klasse ObjectWrapperForBinder-Definition

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

    public ObjectWrapperForBinder(Object data) {
        mData = data;
    }

    public Object getData() {
        return mData;
    }
}

Methode 2

  • für den Absender
    1. verwenden Sie eine benutzerdefinierte native Methode, um Ihr Java-Objekt zur globalen JNI-Referenztabelle hinzuzufügen (über JNIEnv :: NewGlobalRef).
    2. setze die return integer-Zahl (eigentlich JNIEnv :: NewGlobalRef gibt jobject zurück, was ein Zeiger ist, wir können ihn sicher in int umwandeln) an deine Intent (via Intent :: putExtra)
  • für den Empfänger
    1. integer von Intent erhalten (via Intent :: getInt) 
    2. verwenden Sie eine angepasste native Methode, um Ihr Java-Objekt aus der globalen JNI-Referenztabelle wiederherzustellen (über JNIEnv :: NewLocalRef).
    3. element aus der globalen Referenztabelle von JNI entfernen (über JNIEnv :: DeleteGlobalRef),

Methode 2 hat jedoch ein kleines, aber schwerwiegendes Problem: Wenn der Empfänger das Java - Objekt nicht wiederherstellen kann (beispielsweise tritt vor dem Wiederherstellen des Java - Objekts eine Ausnahme ein oder ist die Empfängeraktivität überhaupt nicht vorhanden), wird das Java - Objekt zu einem Verwaist- oder Speicherverlust... Methode 1 hat dieses Problem nicht, da der Android-Binder diese Ausnahme behandelt

Methode 3

Um das Java-Objekt aus der Ferne aufzurufen, erstellen wir einen Datenvertrag/eine Schnittstelle zur Beschreibung des Java-Objekts. Wir verwenden die Hilfsdatei

IDataContract.aidl

package com.example.objectwrapper;
interface IDataContract {
    int func1(String arg1);
    int func2(String arg1);
}

Code für die erste Aktivität

    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 für die zweite Aktivität:

Ändern Sie das Attribut Android: process in AndroidManifest.xml in einen nicht leeren Prozessnamen, um sicherzustellen, dass die zweite Aktivität in einem anderen Prozess ausgeführt wird.

    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();
    }

Auf diese Weise können wir eine Schnittstelle zwischen zwei Aktivitäten übergeben, auch wenn diese in unterschiedlichen Prozessen ausgeführt werden, und die Schnittstellenmethode remote aufrufen

Methode 4

methode 3 scheint nicht einfach genug zu sein, da wir eine Hilfsschnittstelle implementieren müssen .. Wenn Sie nur eine einfache Aufgabe ausführen möchten und der Rückgabewert der Methode nicht erforderlich ist, können Sie Android.os.Messenger verwenden

Code für die erste Aktivität (Absender):

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 für die zweite Aktivität (Empfänger):

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();
        }

    }
}

Alle Messenger.send werden asynchron und sequentiell in einem Handler ausgeführt.

Eigentlich ist Android.os.Messenger auch eine Hilfsschnittstelle. Wenn Sie den Android-Quellcode haben, können Sie eine Datei mit dem Namen IMessenger.aidl finden 

package Android.os;

import Android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}
31
Yessy

Ich habe eine Einzelhelferklasse erstellt, die temporäre Objekte enthält.

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;
    }
}

Anstatt Ihre Objekte in Intent zu setzen, verwenden Sie IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

In Ihrer neuen Aktivität können Sie das Objekt abrufen:

Object obj = (Object) IntentHelper.getObjectForKey("key");

Beachten Sie, dass das Objekt nach dem Laden entfernt wird, um unnötige Verweise zu vermeiden. 

25
Roger Sanoli

Es gibt verschiedene Möglichkeiten, auf Variablen oder Objekte in anderen Klassen oder Aktivitäten zuzugreifen.

Eine Datenbank

B. Gemeinsame Einstellungen.

C. Objektserialisierung.

D. Eine Klasse, die allgemeine Daten enthalten kann, kann als allgemeine Dienstprogramme bezeichnet werden. Es hängt von dir ab.

E. Weitergabe von Daten über Intents und Parcelable Interface.

Das hängt von Ihren Projektanforderungen ab.

A. Datenbank

SQLite ist eine Open-Source-Datenbank, die in Android eingebettet ist. SQLite unterstützt Standardfunktionen für relationale Datenbanken wie SQL-Syntax, Transaktionen und vorbereitete Anweisungen.

Tutorials

B. Gemeinsame Einstellungen

Angenommen, Sie möchten den Benutzernamen speichern. Es wird also jetzt zwei Dinge geben, einen Schlüssel Benutzername, Wert Wert .

Wie ist es aufzubewahren?

 // 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();

Mit putString (), putBoolean (), putInt (), putFloat () und putLong () können Sie den gewünschten Datentyp speichern.

Wie holt man

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.Android.com/reference/Android/content/SharedPreferences.html

C. Objektserialisierung

Die Objekt-Serlisierung wird verwendet, wenn wir einen Objektstatus speichern möchten, um ihn über ein Netzwerk zu senden, oder Sie können ihn auch für Ihren Zweck verwenden.

Verwende Java Beans und speichere sie als eines seiner Felder und verwende Getter und Setter dafür.

JavaBeans sind Java Klassen mit Eigenschaften. Stellen Sie sich Eigenschaften als private Instanzvariablen vor. Da sie privat sind, können sie nur über Methoden in der Klasse von außerhalb ihrer Klasse aufgerufen werden. Die Methoden, die den Wert einer Eigenschaft ändern, heißen Setter-Methoden, und die Methoden, die den Wert einer Eigenschaft abrufen, heißen Getter-Methoden.

public class VariableStorage implements Serializable  {

    private String inString;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }
}

Stellen Sie die Variable in Ihrer E-Mail-Methode mit ein

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

Verwenden Sie dann die Objektserialisierung, um dieses Objekt zu serialisieren, und deserialisieren Sie dieses Objekt in Ihrer anderen Klasse.

Bei der Serialisierung kann ein Objekt als eine Folge von Bytes dargestellt werden, die die Daten des Objekts sowie Informationen über den Objekttyp und die im Objekt gespeicherten Datentypen enthält.

Nachdem ein serialisiertes Objekt in eine Datei geschrieben wurde, kann es aus der Datei gelesen und deserialisiert werden. Das heißt, die Typinformationen und Bytes, die das Objekt und seine Daten darstellen, können verwendet werden, um das Objekt im Speicher neu zu erstellen.

Wenn Sie ein Tutorial dazu wünschen, lesen Sie:

D. CommonUtilities

Sie können selbst eine Klasse erstellen, die allgemeine Daten enthalten kann, die Sie häufig in Ihrem Projekt benötigen.

Probe

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Daten durch Absichten weitergeben

Informationen zur Übergabe von Daten finden Sie in der Anleitung Android - Paketdaten für die Übergabe zwischen Aktivitäten mit Parcelable-Klassen.

23
Nikhil Agrawal

Erstellen Sie Ihre eigene Klasse Customer wie folgt:

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;
    }

}

In Ihrer onCreate()-Methode

@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); 
}

In der Klasse xyz activity müssen Sie den folgenden Code verwenden:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
18
Mayur Chudasama
public class MyClass implements Serializable{
    Here is your instance variable
}

Nun möchten Sie das Objekt dieser Klasse in startActivity übergeben. Verwenden Sie einfach folgendes:

Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);

Dies funktioniert hier, weil MyClass Serializable implementiert.

15
Dhiral Pandya

Der beste Weg ist, eine Klasse (nennen Sie sie Control) in Ihrer Anwendung, die eine statische Variable vom Typ 'Customer' (in Ihrem Fall) enthält. Initialisieren Sie die Variable in Ihrer Aktivität A.

Zum Beispiel:

Control.Customer = CustomerClass;

Gehen Sie dann zu Aktivität B und holen Sie es von der Control-Klasse ab. Vergessen Sie nicht, nach der Verwendung der Variablen eine Null zuzuweisen, da sonst Speicherplatz verschwendet wird.

15
Umesh

Wenn Sie die von Samuh beschriebene Methode wählen, denken Sie daran, dass nur Grundwerte gesendet werden können. Das heißt, Werte, die parcable sind. Wenn Ihr Objekt komplexe Objekte enthält, werden diese nicht folgen. Zum Beispiel Variablen wie Bitmap, HashMap usw ... Diese sind schwierig zu durchlaufen.

Im Allgemeinen würde ich Ihnen raten, nur primitive Datentypen als Extras wie String, Int, Boolean usw. zu senden. In Ihrem Fall wäre dies: String fname, String lname, int age und String address.

Meiner Meinung nach: Komplexere Objekte werden durch die Implementierung einer ContentProvider , SDCard usw. besser gemeinsam genutzt. Es ist auch möglich, eine static-Variable zu verwenden, dies kann jedoch schnell zu fehleranfälligem Code führen. ..

Aber es ist auch nur meine subjektive Meinung.

12
Vidar Vestnes

Ich verwende Parcelable, um Daten von einer Aktivität zu einer anderen Aktivität zu senden. Hier ist mein Code, der in meinem Projekt gut funktioniert.

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});
    }
}

In activityA benutze es so:

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);

In ActivityB verwenden Sie es so, um Daten abzurufen:

Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");
8
Bebin T.N

Sie können versuchen, diese Klasse zu verwenden. Die Einschränkung ist, dass es nicht außerhalb eines Prozesses verwendet werden kann.

Eine Tätigkeit:

 final Object obj1 = new Object();
 final Intent in = new Intent();
 in.putExtra(EXTRA_TEST, new Sharable(obj1));

Andere Tätigkeit:

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);
    }
}
7
Varis

Diese Frage wird auch in einer anderen Frage zum Stapelüberlauf erörtert. Bitte werfen Sie einen Blick auf eine Lösung, um Daten absichtlich mit Serializable zu übergeben . Der Hauptpunkt ist die Verwendung des Objekts Bundle, das die erforderlichen Daten in Intent speichert.

 Bundle bundle = new Bundle();

 bundle.putSerializable(key1, value1);
 bundle.putSerializable(key2, value2);
 bundle.putSerializable(key3, value3);

 intent.putExtras(bundle);

So extrahieren Sie Werte:

 Bundle bundle = new Bundle();

 for (String key : bundle.keySet()) {
 value = bundle.getSerializable(key));
 }

Vorteil von Serializable ist seine Einfachheit. Sie sollten jedoch in Betracht ziehen, die Parcelable -Methode zu verwenden, wenn viele Daten übertragen werden müssen, da Parcelable speziell für Android entwickelt wurde und effizienter ist als Serializable. Sie können eine Parcelable Klasse erstellen mit:

  1. ein Online-Tool - Paketversand
  2. ein Plugin für Android Studio - Android Parcelable Code Generator
6
Ayaz Alifov

Erstellen Sie eine Klasse wie die Bean-Klasse und implementieren Sie die Serializable-Schnittstelle. Dann können wir es durch die intent-Methode leiten, zum Beispiel:

intent.putExtra("class", BeanClass);

Dann holen Sie es sich aus der anderen Aktivität, zum Beispiel: 

BeanClass cb = intent.getSerializableExtra("class");
5
user3289522

Erstellen Sie auf diese Weise zwei Methoden in Ihrer benutzerdefinierten Klasse

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();
        } 
    }
}

Jetzt in Ihrer Senderaktivität so machen

Qabir q= new Qabir(22,"KQ");    
Intent in=new Intent(this,SubActivity.class);
in.putExtra("obj", q.toJSON());
startActivity( in);

Und in Ihrem Empfänger Aktivität

Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));
5
Q07

Starten Sie eine weitere Aktivität aus dieser Aktivität und übergeben Sie die Parameter über das Bündelobjekt

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "[email protected]");
startActivity(intent);

Daten einer anderen Aktivität abrufen (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

Dies ist für einfache Datentypen in Ordnung. Wenn Sie jedoch komplexe Daten zwischen den Aktivitäten übergeben möchten. Sie müssen es zuerst serialisieren.

Hier haben wir Employee Model

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Sie können die von Google bereitgestellte Gson lib verwenden, um die komplexen Daten Wie folgt zu serialisieren

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);
5
DroidNinja

Ja, die Verwendung eines statischen Objekts ist bei benutzerdefinierten nicht serialisierbaren Objekten bei weitem die einfachste Methode.

3
alistair

Android-Aktivitätsobjekte können zerstört und wiederhergestellt werden. Sie müssen also einen anderen Ansatz verwenden, um sie - oder jedes von ihnen erstellte Objekt zu suchen !!! - auf. Das heißt, Sie könnten als statische Klassenreferenz übergeben werden, aber dann wird das Objekt-Handle (Java nennt diese "Verweise" wie Smalltalk; sie sind jedoch keine Verweise im Sinne von C oder Assembly) möglicherweise später ungültig, da ein "Feature" Von Android OE kann jede Aktivität später vernichtet und wiederhergestellt werden.

Die ursprüngliche Frage stellte die Frage "Wie man ein Objekt in Android von einer Aktivität zu einer anderen übergibt" und niemand hat darauf geantwortet. Sicherlich können Sie serialisiert (Serializable, Parcelable, von/nach JSON) und eine Kopie der Objektdaten übergeben und ein neues Objekt mit denselben Daten kann erstellt werden. aber es wird NICHT die gleichen Referenzen/Handles haben. Außerdem können viele andere erwähnt werden, dass Sie die Referenz in einem statischen Speicher speichern können. Und das wird funktionieren, wenn sich Android nicht dafür entscheidet, Ihre Aktivität zu zerstören. 

Um die ursprüngliche Frage wirklich zu lösen, benötigen Sie eine statische Suche. Jedes Objekt aktualisiert seine Referenz, wenn/wenn es neu erstellt wird. Z.B. Jede Android-Aktivität würde sich beim Aufruf von onCreate erneut aufheben. Sie können auch sehen, wie einige Personen die Aufgabenliste verwenden, um eine Aktivität anhand ihres Namens zu suchen. (Das System zerstört diese Instanz der Aktivität vorübergehend, um Speicherplatz zu sparen .. getRunningTasks. Die Aufgabenliste ist effektiv eine spezialisierte Auflistung der neuesten Objektinstanz jeder Aktivität.).

Als Referenz:

Gestoppt: "Die Aktivität wird vollständig durch eine andere Aktivität verdeckt (die Aktivität befindet sich jetzt im" Hintergrund "). Eine gestoppte Aktivität ist ebenfalls noch am Leben (das Activity-Objekt wird im Speicher gehalten, behält jedoch alle Status- und Memberinformationen bei ist nicht an den Fenstermanager angehängt), ist jedoch für den Benutzer nicht mehr sichtbar und kann vom System abgebrochen werden, wenn Speicher an anderer Stelle benötigt wird. "

onDestroy "system ist vorübergehend zerstört diese Instanz der Aktivität, um Speicherplatz zu sparen."

Der Message Bus ist also eine praktikable Lösung. Im Grunde "schlägt". Anstatt zu versuchen, Referenzen auf Objekte zu haben; Anschließend entwerfen Sie Ihren Entwurf neu, um MessagePassing anstelle von SequentialCode zu verwenden. Exponentiell schwieriger zu debuggen; Sie können jedoch diese Art von Betriebsumgebungsverständnissen ignorieren. In der Tat wird jeder Objektmethodenzugriff umgekehrt, so dass der Aufrufer eine Nachricht bereitstellt und das Objekt selbst einen Handler für diese Nachricht definiert. Viel mehr Code, kann es aber mit den Einschränkungen der Android-OE robust machen.

Wenn Sie nur die oberste Aktivität wünschen (typisch für Android-Apps, da "Kontext" überall benötigt wird), können Sie einfach jede Aktivität selbst als "top" im statischen globalen Bereich anzeigen lassen, wenn onResume aufgerufen wird. Dann kann Ihr AlertDialog oder was auch immer einen Kontext benötigt, diesen einfach abrufen. Es ist auch ein bisschen glücklich, ein globales Element zu verwenden, es kann jedoch einfacher sein, einen Kontext überall hin und her zu verschieben. Wenn Sie einen MessageBus verwenden, ist es auf jeden Fall IT IS global. 

3
TimJowers2
  1. Ich weiß, dass statisch schlecht ist, aber es scheint, dass wir hier gezwungen sind, es zu benutzen. Das Problem bei Parceables/Seriazables besteht darin, dass die beiden Aktivitäten doppelte Instanzen desselben Objekts haben = Verschwendung von Speicher und CPU.

    public class IntentMailBox {
        static Queue<Object> content = new LinkedList<Object>();
    }
    

Aufrufende Aktivität

IntentMailBox.content.add(level);
Intent intent = new Intent(LevelsActivity.this, LevelActivity.class);
startActivity(intent);

Aufgerufene Aktivität (beachten Sie, dass onCreate () und onResume () mehrmals aufgerufen werden kann, wenn das System Aktivitäten zerstört und neu erstellt).

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Eine andere Möglichkeit besteht darin, ein statisches Feld der Klasse zu deklarieren, das Sie in genau dieser Klasse übergeben möchten. Es wird nur zu diesem Zweck dienen. Vergessen Sie nicht, dass es in onCreate null sein kann, da Ihr App-Paket vom System entladen und später erneut geladen wurde.

  2. Wenn Sie bedenken, dass Sie den Aktivitätslebenszyklus immer noch abwickeln müssen, möchten Sie möglicherweise alle Daten direkt in die gemeinsamen Einstellungen schreiben, was mit den komplexen Datenstrukturen so schwierig ist, wie sie sind.

2
Anton Duzenko

Die obigen Antworten sind fast alle richtig, aber für diejenigen, die diese Antworten nicht verstehenAndroid verfügt über eine leistungsfähige Klasse Intent Mit deren Hilfe teilen Sie Daten nicht nur zwischen Aktivitäten, sondern auch anderen Komponenten von Android (Broadcasr-Empfänger, Server für Inhalte) vorausgesetzt, wir verwenden die ContetnResolver-Klasse no Intent) . In Ihrer Aktivität bauen Sie Absicht auf

Intent intent = new Intent(context,SomeActivity.class);
intent.putExtra("key",value);
startActivity(intent);

In Ihrer Empfangsaktivität haben Sie

public class SomeActivity extends AppCompactActivity {

    public void onCreate(...){
    ...
          SomeObject someObject = getIntent().getExtras().getParceable("key");
    }

}

Sie müssen die Schnittstelle "Parceable" oder "Serializable" in Ihrem Objekt implementieren, um die Aktivitäten untereinander zu teilen. Es ist schwierig, Parcealbe statt Serializable Interface auf einem Objekt zu implementieren. Deshalb hat Android speziell für dieses Plugin ein Plug-In. Laden Sie es herunter und verwenden Sie es

1
Sardor Islomov

Objekt von einer Aktivität an eine andere Aktivität übergeben 

(1) Quellenaktivität

Intent ii = new Intent(examreport_select.this,
                    BarChartActivity.class);

            ii.putExtra("IntentExamResultDetail",
                    (Serializable) your List<ArraList<String>> object here);
            startActivity(ii);

(2) Zielaktivität

List<ArrayList<String>> aa = (List<ArrayList<String>>) getIntent()
            .getSerializableExtra("IntentExamResultDetail");
0
Jayesh Kalkani

Wir können das Objekt von einer Aktivität an eine andere Aktivität übergeben:

SupplierDetails poSuppliersDetails = new SupplierDetails();

In poSuppliersDetails haben wir einige Werte. Jetzt sende ich dieses Objekt an die Zielaktivität:

Intent iPODetails = new Intent(ActivityOne.this, ActivityTwo.class);
iPODetails.putExtra("poSuppliersDetails", poSuppliersDetails);

So erhalten Sie dies in ACtivityTwo:

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");
0
user4715375

Übergeben Sie eine Aktivität an eine andere:

startActivity(new Intent(getBaseContext(),GetActivity.class).putExtra("passingkey","passingvalue"));

Werte erhalten:

String myvalue= getIntent().getExtras("passingkey");

Ich habe das Objekt mit Pacelable oder Serializable für die Übertragung festgelegt. Wenn ich jedoch weitere Variablen zum Objekt (Modell) hinzufüge, muss ich alles registrieren. Es ist so unbequem. 

Es ist sehr einfach, Objekte zwischen Aktivitäten oder Fragmenten zu übertragen. 

Android DataCache

0
kimkevin

Ich hatte mich immer gefragt, warum dies nicht so einfach sein kann, als in eine Methode der anderen Aktivität zu gerufen. Ich habe vor kurzem eine Utility-Bibliothek geschrieben, die es fast so einfach macht. Sie können es hier ausprobieren ( https://github.com/noxiouswinter/gnlib_Android/wiki/gnlauncher ). 

GNLauncher macht das Senden von Objekten/Daten zu einer Aktivität aus einer anderen Aktivität usw. so einfach wie das Aufrufen einer Funktion in der Aktivität mit den erforderlichen Daten als Parameter. Es führt die Typensicherheit ein und beseitigt alle Mühe, die Serialisierung durchzuführen, indem sie mit Hilfe von String-Schlüsseln an die Absicht angefügt wird und diese am anderen Ende rückgängig macht.

Verwendungszweck

Definieren Sie eine Schnittstelle mit den Methoden, die Sie für die zu startende Aktivität aufrufen möchten.

public interface IPayload {
    public void sayHello(String name, int age);
}

Implementieren Sie die obige Schnittstelle für die zu startende Aktivität in ..__, und benachrichtigen Sie GNLauncher auch, wenn die Aktivität fertig ist.

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);
    }
}

Rufen Sie in der anderen Aktivität einen Proxy zur obigen Aktivität auf und rufen Sie eine beliebige Methode mit den gewünschten Parametern auf.

public class Activity_2 extends Activity {
    public void onClick(View v) {
        ((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
    }
}

Die erste Aktivität wird gestartet und die Methode mit den erforderlichen Parametern aufgerufen.

Voraussetzungen

Weitere Informationen zum Hinzufügen von Abhängigkeiten finden Sie unter https://github.com/noxiouswinter/gnlib_Android/wiki#prerequisites

0
jinais