Jak przekazać obiekt z jednej aktywności do drugiej na Androidzie

Próbuję pracować nad wysłaniem obiektu mojej klasy klienta z jednej Activity i wyświetlaniem go w innej Activity.

Kod dla klasy Klienta:

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

Chcę wysłać jego obiekt z jednego Activity do drugiego, a następnie wyświetlić dane na drugim Activity.

Jak mogę to osiągnąć?

Author: Swati Garg, 2010-04-29

30 answers

Jedną z opcji może być pozwolenie twojej klasie zaimplementować interfejs Serializable, a następnie możesz przekazać instancje obiektów w Intent extra używając putExtra(Serializable..) wariantu metody Intent#putExtra().

Pseudocode:

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

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

Uwaga: Upewnij się, że każda zagnieżdżona Klasa głównej niestandardowej klasy ma zaimplementowany interfejs Serializowalny, aby uniknąć wyjątków od serializacji. Na przykład:

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}
 741
Author: Samuh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-26 12:35:03

Zaimplementuj swoją klasę z Serializowalnym. Załóżmy, że jest to klasa encji:

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

Wysyłamy obiekt o nazwie dene z aktywności X do aktywności Y. Somewhere in x activity;

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

W aktywności Y otrzymujemy obiekt.

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");
To wszystko.
 266
Author: Mustafa Güven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:20:06
  • Używanie globalnych zmiennych statycznych nie jest dobrą praktyką inżynierii oprogramowania .
  • Konwersja pól obiektu na prymitywne typy danych może być gorączkowym zadaniem.
  • Używanie serializowalne jest OK, ale nie jest wydajne na platformie Android.
  • Parcelable jest specjalnie zaprojektowany dla Androida i powinieneś z niego korzystać. Oto prosty przykład: przekazywanie obiektów niestandardowych między Androidem działania

Możesz wygenerować Parcelowalny kod dla twojej klasy używając tej strony .

 106
Author: SohailAziz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 06:21:34

Podczas wywoływania aktywności

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);
W toClass.java odbiera aktywność przez
Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

Upewnij się, że Klasa klienta implementuje 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();
    }
 86
Author: Ads,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-08 20:39:33

Z mojego doświadczenia wynika, że są trzy główne rozwiązania, każde z ich wadami i zaletami:

  1. Implementing Parcelable

  2. Implementacja Serializable

  3. Korzystanie z lekkiej biblioteki magistrali zdarzeń (na przykład EventBus Greenrobota lub Otto Square)

Parcelable - szybki i standardowy Android, ale ma dużo kodu kotła i wymaga mocno zakodowanych ciągów w celach informacyjnych podczas ciągnięcia wartości intencji (nie-mocno wpisane).

Seriale - zbliżony do zera boilerplate, ale jest to najwolniejsze podejście i wymaga również mocno zakodowanych ciągów podczas wyciągania wartości z intencji (nie-mocno wpisanych).

Event Bus - zero boilerplate, najszybsze podejście i nie wymaga ciężko zakodowanych ciągów, ale wymaga dodatkowej zależności (choć zwykle lekka, ~40 KB)

Zamieściłem bardzo szczegółowe porównanie wokół te trzy podejścia, w tym wskaźniki efektywności.

 77
Author: Steven Mark Ford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-11 08:09:57

Użyj gson , aby przekonwertować obiekt na JSON i przekazać go przez intent. W nowej aktywności Konwertuj plik JSON na obiekt.

W Twoim build.gradle dodaj to do swoich zależności

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

W aktywności przekonwertuj obiekt na JSON-string:

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

W aktywności otrzymującej, przekonwertuj łańcuch json z powrotem na oryginalny obiekt:

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

DlaKotlin to całkiem to samo

Podaj dane

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

Odbiór danych

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)
 64
Author: khalid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 09:27:35

Można również zapisać dane obiektu do tymczasowych łańcuchów i ints i przekazać je do działania. Oczywiście w ten sposób otrzymujesz dane, ale nie sam obiekt.

Ale jeśli po prostu chcesz je wyświetlić, a nie używać obiektu w innej metodzie lub czegoś podobnego, powinno to wystarczyć. Zrobiłem to w ten sam sposób, aby wyświetlić dane z jednego obiektu w innej aktywności.

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);
Można też podać je bezpośrednio zamiast temp ivarów, ale w ten sposób moim zdaniem jest jaśniejszy. Dodatkowo możesz ustawić temp ivars na null, aby wcześniej były czyszczone przez GarbageCollector. Powodzenia!

Na marginesie: override toString() zamiast pisania własnej metody drukowania.

Jak wspomniano w komentarzach poniżej, w ten sposób odzyskujesz dane w innej aktywności:

String fName = getIntent().getExtras().getInt("fname");
 37
Author: MJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:13:56

Znalazłem prostą i elegancką metodę:

  • NO Parcelable
  • brak seriali
  • brak pola statycznego
  • No Event Bus

Metoda 1

Kod dla pierwszej czynności:

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

Kod dla drugiej czynności:

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

Znajdziesz objSent & objReceived mają te same hashCode, więc są identyczne.

Ale dlaczego możemy przekazać obiekt java w tym sposób?

W rzeczywistości Android binder utworzy globalne odniesienie JNI dla obiektu java i zwolni to globalne odniesienie JNI, gdy nie ma odniesienia dla tego obiektu java. binder zapisze globalne odniesienie do JNI w obiekcie Binder.

*uwaga: ta metoda działa tylko, jeśli dwie czynności nie są uruchomione w tym samym procesie, w przeciwnym razie wyrzuć ClassCastException w (ObjectWrapperForBinder)getIntent ().getExtras ().getBinder ("object_value") *

Klasa ObjectWrapperForBinder defination

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Metoda 2

  • dla nadawcy,
    1. użyj własnej natywnej metody, aby dodać obiekt java do globalnej tabeli referencyjnej JNI (poprzez JNIEnv::NewGlobalRef)
    2. umieść return integer(właściwie JNIEnv::NewGlobalRef return jobject, który jest wskaźnikiem, możemy go bezpiecznie wrzucić do int) do Twojej intencji (poprzez Intent::putExtra)
  • dla odbiornika
    1. get integer from Intent (via Intent:: getInt)
    2. Aby przywrócić obiekt java z JNI global reference table (poprzez JNIEnv::NewLocalRef), użyj niestandardowej natywnej metody
  • Usuń element z JNI global reference table (poprzez JNIEnv:: DeleteGlobalRef),

Ale Metoda 2 ma mały, ale poważny problem, jeśli odbiornik nie przywróci obiektu java (na przykład jakiś wyjątek przed przywróceniem obiektu java lub aktywność odbiornika w ogóle nie istnieje), obiekt java stanie się sierota lub wyciek pamięci, Metoda 1 nie ma tego problemu, ponieważ android binder obsłuży ten wyjątek

Metoda 3

Aby zdalnie wywołać obiekt java, utworzymy kontrakt danych / interfejs do opisania obiektu java, użyjemy pliku AIDL

IDataContract.aidl

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

Kod pierwszego działania

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

Kod dla drugiej czynności:

zmień atrybut Android: proces w AndroidManifest.xml do niepustego Nazwa procesu, aby upewnić się, że druga czynność zostanie uruchomiona w innym procesie

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

W ten sposób możemy przekazać interfejs pomiędzy dwoma czynnościami, nawet jeśli działają one w innym procesie, i wywołać metodę interfejsu zdalnie

Metoda 4

Metoda 3 wydaje się nie dość prosta, ponieważ musimy zaimplementować interfejs aidl. Jeśli chcesz wykonać proste zadanie, a wartość zwracana metodą jest niepotrzebna, możemy użyć Androida.os.Messenger

Kod dla pierwszego aktywność (nadawca):

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

Kod dla drugiego działania (odbiornika):

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

    }
}
Wszyscy posłańcy.send będzie uruchamiany asynchronicznie i sekwencyjnie. Właściwie android.os.Messenger jest również interfejsem aidl, jeśli masz kod źródłowy Androida, możesz znaleźć plik o nazwie IMessenger.aidl
package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}
 30
Author: Yessy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 02:34:49

Stworzyłem klasę pomocniczą singleton, która przechowuje tymczasowe obiekty.

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

Zamiast umieszczać obiekty w intencji, użyj IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

Wewnątrz twojej nowej aktywności możesz uzyskać obiekt:

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

Należy pamiętać, że po załadowaniu obiekt jest usuwany, aby uniknąć niepotrzebnych odniesień.

 25
Author: Roger Sanoli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 13:04:10

Istnieje kilka sposobów dostępu do zmiennych lub obiektów w innych klasach lub aktywności.

A. Baza Danych

B. wspólne preferencje.

C. serializacja obiektów.

D. Klasa, która może przechowywać wspólne dane, może być nazwana jako wspólne narzędzia. To zależy od Ciebie.

E. Przekazywanie danych przez Intenty i interfejs Parcelowalny.

To zależy od potrzeb Twojego projektu.

A. Baza Danych

SQLite {[25] } jest otwartym baza danych źródłowych osadzona w systemie Android. SQLite obsługuje standardowe funkcje relacyjnej bazy danych, takie jak składnia SQL, transakcje i przygotowane instrukcje.

Tutoriale

B. wspólne preferencje

Załóżmy, że chcesz zapisać nazwę użytkownika. Więc teraz będą dwie rzeczy, klucz nazwa użytkownika, wartość wartość.

Jak przechowywać

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

używanie putString (), putBoolean (), putInt (), putFloat () i putLong() możesz zapisać żądany dtatype.

Jak aportować

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

Http://developer.android.com/reference/android/content/SharedPreferences.html

C. serializacja obiektów

Object serlization jest używany, jeśli chcemy zapisać stan obiektu, aby wysłać go przez sieć lub możesz go również użyć do swojego celu.

Użyj Java beans i przechowuj w nim jako jedno z jego pól i używaj getterów i setterów do to.

JavaBeans są klasami Javy, które mają właściwości. Pomyśl o właściwości jako zmienne instancji prywatnych. Ponieważ są prywatne, jedynym sposobem mogą być dostępne z zewnątrz ich klasy jest za pomocą metod w klasie. Metody, które zmieniają wartość właściwości, nazywane są metodami setter, a metody, które pobierają wartość właściwości, nazywane są metodami getter.

public class VariableStorage implements Serializable  {

    private String inString;

    public String getInString() {
        return inString;
    }

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

Ustaw zmienną w metodzie mail używając

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

Następnie użyj obiektu serializacja w celu serializacji tego obiektu i w innej klasie deserializacji tego obiektu.

W serializacji obiekt może być reprezentowany jako sekwencja bajtów, która zawiera dane obiektu, a także informacje o typie obiektu i typach danych przechowywanych w obiekcie.

Po zapisaniu serializowanego obiektu do pliku, można go odczytać z pliku i deserializować. Oznacza to, że informacje o typie i bajty, które reprezentują obiekt i jego dane, mogą być użyte do odtworzyć obiekt w pamięci.

Jeśli chcesz tutorial dla tego odnoszą się do:

D. Commonty

Możesz samodzielnie stworzyć klasę, która może zawierać wspólne dane, których często potrzebujesz w swoim projekcie.

Próbka

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Przekazywanie danych poprzez intencje

Zapoznaj się z samouczkiem Android - dane przesyłane pomiędzy działaniami za pomocą klas Parcelable dla tej opcji przekazywania danych.

 23
Author: Nikhil Agrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:32

Najlepszym sposobem jest posiadanie w aplikacji klasy (call it Control), która będzie zawierała zmienną statyczną typu' Customer ' (w Twoim przypadku). Zainicjalizuj zmienną w aktywności A.

Na przykład:

Control.Customer = CustomerClass;

Następnie przejdź do Ćwiczenia B i pobierz go z klasy kontrolnej. Nie zapomnij przypisać null po użyciu zmiennej, w przeciwnym razie pamięć zostanie zmarnowana.

 15
Author: Umesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:14:58
public class MyClass implements Serializable{
    Here is your instance variable
}

Teraz chcesz przekazać obiekt tej klasy w startActivity. Po prostu użyj tego:

Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);
To działa tutaj, ponieważ MyClass implementuje Serializable.
 15
Author: Dhiral Pandya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:21:18

Stwórz własną klasę Customer w następujący sposób:

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

}

W Twojej metodzie onCreate()

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

W klasie xyz activity należy użyć następującego kodu:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
 15
Author: Mayur Chudasama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-02 14:10:42

Jeśli wybierzesz użyj sposobu, w jaki opisuje Samuh, pamiętaj, że tylko prymitywne wartości mogą być wysyłane. Czyli wartości, które można podzielić. Tak więc, jeśli twój obiekt zawiera złożone obiekty, nie będą one następować. Na przykład zmienne takie jak Bitmap, HashMap itp... Są trudne do przejścia przez zamiar.

Ogólnie radzę wysyłać tylko prymitywne typy danych jako dodatki, takie jak String, int, boolean itp. W Twoim przypadku byłoby to: String fname, String lname, int age, i String address.

Moja opinia: więcej złożone obiekty są lepiej współdzielone przez implementację ContentProvider, SDCard , itp. Możliwe jest również użycie zmiennej statycznej , ale może to szybko prowadzić do podatnego na błędy kodu... Ale to tylko moja subiektywna opinia.
 12
Author: Vidar Vestnes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:12:10

używam parcelable do wysyłania danych z jednej aktywności do innej aktywności. Oto Mój kod, który działa dobrze w moim projekcie.

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

w aktywności używaj go tak:

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

w ActivityB użyj go tak, aby uzyskać dane:

Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");
 8
Author: Bebin T.N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 14:09:49

Możesz spróbować użyć tej klasy. Ograniczenie polega na tym, że nie może być używany poza jednym procesem.

Jedna aktywność:

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

Inna aktywność:

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
Author: Varis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:18:38

Kreuje klasę podobną do klasy bean i implementuje interfejs Serializable. Następnie możemy przejść przez metodę intent, na przykład:

intent.putExtra("class", BeanClass);

Następnie Uzyskaj go z innej aktywności, na przykład:

BeanClass cb = intent.getSerializableExtra("class");
 5
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 14:29:13

Utwórz dwie metody w swojej klasie niestandardowej w ten sposób

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

Teraz w aktywności nadawcy rób tak

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

I w aktywności odbiorczej

Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));
 5
Author: Think7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 21:14:42

Uruchom inną aktywność z tej aktywności i przekaż parametry za pomocą obiektu Bundle

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

Pobieranie danych o innej aktywności (Twojej aktywności)

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

To jest ok dla prostego typu danych. Ale jeśli chcesz przekazać złożone dane między aktywnością. Najpierw musisz go zserializować.

Tutaj mamy Model pracownika

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

    getters...
    setters...
}

Możesz użyć Gson lib dostarczonego przez google do serializacji złożonych danych like this

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
Author: DroidNinja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-23 12:06:01

To pytanie jest również omówione w innym pytaniu o przepełnienie stosu. Proszę spojrzeć na rozwiązanie do przekazywania danych przez intent przy użyciu Serializowalnego. Głównym punktem jest użycie Bundle obiektu, który przechowuje niezbędne dane wewnątrz Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

Aby wyodrębnić wartości:

 Bundle bundle = new Bundle();

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

Zaletą Serializable jest jego prostota. Należy jednak rozważyć użycie metody Parcelable, jeśli potrzebujesz wielu danych do przesłania, ponieważ {[5] } jest specjalnie zaprojektowany dla Android i jest bardziej wydajny niż Serializable. Możesz utworzyć Parcelable klasę używając:

  1. narzędzie online - parcelabler
  2. plugin dla Android Studio - Android Parcelable code generator
 5
Author: Sa Qada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-16 12:19:43

Tak, użycie obiektu statycznego jest zdecydowanie najprostszym sposobem na zrobienie tego z niestandardowymi obiektami, które nie są serializowane.

 3
Author: alistair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-13 21:49:45

Obiekty aktywności Androida mogą być niszczone i odtwarzane. Więc, będziesz musiał użyć innego podejścia, aby spojrzeć ich - lub dowolnego obiektu, który tworzą !!! - w górę. Oznacza to, że możesz przekazać jako statyczne odniesienie do klasy, ale wtedy uchwyt obiektu (Java wywołuje te "referencje", podobnie jak SmallTalk; ale nie są one referencjami w sensie C lub assembly) będzie prawdopodobnie nieprawidłowy później, ponieważ" funkcja " Android OE jest każda aktywność może być unicestwiona i odtworzona później.

The oryginalne pytanie zadane "jak przekazać obiekt z jednej aktywności do drugiej w Androidzie" i nikt na to nie odpowiedział. Na pewno można serializować (Serializable, Parcelable, to / from JSON) i przekazać kopię danych obiektu i utworzyć nowy obiekt o tych samych danych; ale nie będzie on miał tych samych referencji/uchwytów. Ponadto wiele innych wspomniało, że możesz przechowywać referencję w sklepie statycznym. I to zadziała, chyba że Android zdecyduje się na zniszczenie Twojej aktywności.

Więc, do really solve the original question you would need a static lookup plus each object will update its reference when / if it is recreated. Na przykład każda aktywność Androida będzie się relist sama, jeśli jego onCreate jest wywoływany. Możesz również zobaczyć, jak niektórzy ludzie używają listy zadań do wyszukiwania aktywności po nazwie. (system tymczasowo niszczy tę instancję aktywności, aby zaoszczędzić miejsce..getRunningTasks, Lista zadań jest w rzeczywistości wyspecjalizowaną listą najnowszych instancji obiektów każdego Aktywność).

Dla odniesienia:

Zatrzymany: "Aktywność jest całkowicie zasłonięta przez inną aktywność (aktywność jest teraz w "tle"). Zatrzymana aktywność jest również nadal żywa (obiekt aktywności jest przechowywany w pamięci , zachowuje wszystkie informacje o stanie i członie, ale nie jest dołączony do menedżera okien). Jednak nie jest już widoczny dla użytkownika i może zostać zabity przez system, gdy pamięć jest potrzebna gdzie indziej."

OnDestroy "system tymczasowo niszczy tę instancję działania, aby zaoszczędzić miejsce."

Więc Szyna komunikatów jest wykonalnym rozwiązaniem. To w zasadzie "punts". Zamiast próbować mieć odniesienia do obiektów; następnie przebudowujesz swój projekt, aby użyć MessagePassing zamiast SequentialCode. Wykładniczo trudniejsze do debugowania; ale pozwala ignorować tego typu działania. Skutecznie, każdy dostęp do metody obiektu jest odwrócony, więc wywołujący wysyła wiadomość i sam obiekt definiuje funkcję obsługi tej wiadomości. Dużo więcej kodu, ale może sprawić, że będzie solidny z ograniczeniami OE Androida.

Jeśli wszystko, co chcesz, to najwyższa aktywność (typowa rzecz w aplikacjach na Androida ze względu na "kontekst" jest potrzebny wszędzie), możesz po prostu mieć każdą aktywność jako "top" w statycznej przestrzeni globalnej, gdy zostanie wywołana jego onResume. Następnie twój AlertDialog lub cokolwiek, co wymaga kontekstu, może po prostu go stamtąd pobrać. Ponadto, jej trochę yucky do korzystania z globalnego, ale może upraszczając przekazywanie kontekstu w górę iw dół wszędzie i, na pewno, gdy używasz Messagebusa, to i tak jest globalny.

 3
Author: TimJowers2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 15:26:02
  1. Wiem, że statyka jest zła, ale wydaje się, że jesteśmy zmuszeni użyć jej tutaj. Problem z parceables / seriazables polega na tym, że dwie czynności mają zduplikowane instancje tego samego obiektu = strata pamięci i procesora.

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

Wywołanie aktywności

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

Wywołana aktywność (zauważ, że OnCreate()i onResume () może być wywołana wiele razy, gdy system niszczy i odtwarza działania)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Innym sposobem jest zadeklarowanie statycznego pola klasy, które chcesz przekazać w tej właśnie klasie. Będzie służył tylko do tego celu. Nie zapominaj, że może być null w onCreate, ponieważ pakiet aplikacji został rozładowany z pamięci przez system i przeładowany później.

  2. Mając na uwadze, że nadal musisz obsługiwać cykl życia aktywności, możesz chcieć zapisać wszystkie dane bezpośrednio do wspólnych preferencji, co jest bolesne przy złożonych strukturach danych jako tak.

 2
Author: Anton Duzenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 13:45:20

Powyżej odpowiedzi prawie wszystkie poprawne, ale dla tych, którzy nie znają tych odpowiedzi Android ma potężną klasę Intent za jej pomocą udostępniasz dane nie tylko między aktywnością, ale innymi komponentami Androida (odbiornik broadcasr, serwery dla treści zapewniają używamy klasy ContetnResolver no Intent). W swojej działalności budujesz intencję

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

W swojej aktywności masz

public class SomeActivity extends AppCompactActivity {

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

}

Musisz zaimplementować na swoim obiekcie interfejs szeregowy lub Serializowalny w kolejność dzielenia się działaniami. Trudno zaimplementować Parcealbe zamiast Serializowalny interfejs na obiekcie dlatego android ma specjalnie do tego plugin.Pobierz go i użyj

 1
Author: Sardor Islomov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-14 16:42:07

Zawsze zastanawiałem się, dlaczego to nie może być tak proste, jak wywołanie metody innej aktywności. Niedawno napisałem bibliotekę narzędzi, która sprawia, że jest to prawie tak proste. Możesz to sprawdzić tutaj ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).

GNLauncher sprawia, że wysyłanie obiektów/danych do aktywności z innej aktywności itp.jest tak proste, jak wywołanie funkcji w aktywności z wymaganymi danymi jako parametrami. Wprowadza bezpieczeństwo typu i usuwa wszystkie hasty konieczności serializacji, dołączanie do intencji za pomocą kluczy łańcuchowych i cofanie tego samego na drugim końcu.

Użycie

Zdefiniuj interfejs z metodami, które chcesz wywołać w aktywności do uruchomienia.

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

Zaimplementuj powyższy interfejs na aktywności do uruchomienia. Powiadom również GNLauncher, gdy aktywność jest gotowa.

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

W drugiej aktywności, uzyskaj proxy do powyższej aktywności i wywołaj dowolną metodę z żądaną parametry.

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

Zostanie uruchomiona pierwsza aktywność i wywołana metoda z wymaganymi parametrami.

Warunki wstępne

Proszę odnieść się do https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites aby dowiedzieć się, jak dodać zależności.

 0
Author: jinais,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-07 18:36:33

Przekazuje obiekt z jednej aktywności do innej aktywności.

(1) aktywność Źródła

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

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

(2) aktywizacja miejsca przeznaczenia

List<ArrayList<String>> aa = (List<ArrayList<String>>) getIntent()
            .getSerializableExtra("IntentExamResultDetail");
 0
Author: Jayesh Kalkani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 05:48:30

Kiedyś ustawiałem obiekt z Pacelable lub Serializable do transferu, ale za każdym razem, gdy dodaję inne zmienne do obiektu (modelu), muszę to wszystko zarejestrować. To takie niewygodne.

Bardzo łatwo jest przenosić obiekt między działaniami lub fragmentami.

Android DataCache

 0
Author: kimkevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-04 11:44:57

Możemy przekazać obiekt z jednej aktywności do innej aktywności:

SupplierDetails poSuppliersDetails = new SupplierDetails();

Wewnątrz poSuppliersDetails mamy pewne wartości. Teraz wysyłam ten obiekt do aktywności docelowej:

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

Jak to zrobić w ACtivityTwo:

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");
 0
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 15:04:36

Przekazać jedną czynność do drugiej:

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

Pobierz wartości:

String myvalue= getIntent().getExtras("passingkey");
 0
Author: Bhuvaneshwaran Vellingiri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 14:24:52

Witam wszystkich widze duzo dobrych opcji ale zastanawialem sie dlaczego Oprawa nie zostala uzywana?

[4]}przekazywanie odniesienia do obiektu wydaje mi się bardziej efektywne niż serializowanie i desterylizowanie obiektów, ale nie zanurkowałem głęboko, aby sprawdzić, czy to jest to, co dzieje się za kulisami.

Tworzenie segregatora jest dość proste...

public class MyBinder extends Binder {

    private Object myObject;

    public MyBinder(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

}

A tworzenie parcelable to use it isn ' t that bad ether.

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

    };
}

Ta logika jest naprawdę fajna, bo ty są rzeczywiście przekazywanie odniesienia z aktywności do aktywności.

Radziłbym sprawdzić czy null i czy instance of Binder to MyBinder!

I zaimplementować to po prostu...

Send it off

Object myObject = "some object";
MyParcelable myParcelable = new MyParcelable();
myParcelable.setObject(myObject);

intent.putExtra("MyParcelable", myParcelable);

Get it back

myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();
Heck ktoś mógłby zwariować i zrobić z tego frajera prawdziwego generyka.
 -1
Author: SkidRunner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-13 19:03:21