Intents kullanarak bir Android Etkinliğinden diğerine nesne nasıl gönderilir?


849

Özel türden bir nesneyi Intent sınıfının yöntemini kullanarak bir Etkinlikten diğerine nasıl geçirebilirim ?putExtra()


@UMMA - sorularınızı "Topluluk Wiki" olarak işaretlemeye devam etmenize gerek yok. Buraya bir göz atın: meta.stackexchange.com/questions/11740/…
Dave Webb

1
@Paresh: sağladığınız bağlantı koptu. Bir alternatif sağlayabilir misiniz?
antiplex



Basit ve zarif bir yöntem buldum stackoverflow.com/a/37774966/6456129
Yessy

Yanıtlar:


751

Sadece nesneleri etrafta geçiriyorsanız Parcelable bunun için tasarlanmıştır. Java'nın yerel serileştirmesini kullanmaktan biraz daha fazla çaba gerektiriyor, ancak bu çok daha hızlı (ve demek istediğim, WAY daha hızlı).

Dokümanlardan, nasıl uygulanacağına dair basit bir örnek:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Belirli bir Parsel'den almak için birden fazla alanınız olması durumunda, bunları bunları koyduğunuz sırayla (yani, bir FIFO yaklaşımında) yapmanız gerektiğini gözlemleyin.

Eğer nesneleri sonra uygulamak Parcelablesadece sizin içine koyarak meselesi niyet ile putExtra () :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Ardından getParcelableExtra () ile bunları geri çekebilirsiniz :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Nesne Sınıfınız Parcelable ve Serializable kullanıyorsa, aşağıdakilerden birine yayın yaptığınızdan emin olun:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
MData bir int değil, bir nesne (örn. JSONObject) olduğunda bu nasıl uygulanır?
Peter Ajtai

301
Neden bütün bunlar olmadan nesneyi geçemezsiniz? Halihazırda hafızada olan bir nesneyi aktarmak istiyoruz.
ceklock

110
@tecnotron beacuse uygulamaları farklı işlemlerde ve ayrı bellek adres alanlarına sahip, işleminizdeki bellek bloğuna yalnızca işaretçi (referans) gönderemez ve başka bir işlemde kullanılabilir olmasını bekleyebilirsiniz.
marcinj

12
Nesnenin sınıfını serileştirilebilir veya Parceable yapamazsam ne yapmalıyım?
Amel Jose

11
@ceklock bunun sebebi şu şekildedir: Etkinlik geride kaldığında ve daha sonra bellekten öldürüldüğünde ve kullanıcı onu son günler menüsünden açtığında, kaldığı yerde Etkinlik oluşturmanız gerekir. Aynı kullanıcı arayüzü olmalıdır. Bu durumda nesne bellekte değildir. Ama niyet bu.
tasomaniac

194

Nesnenizi bir tür dize temsiline serileştirmeniz gerekir. Olası bir dize gösterimi JSON'dur ve bana sorarsanız android'de JSON'a / JSON'dan serileştirmenin en kolay yollarından biri Google GSON'dur .

Bu durumda, dize dönüş değerini yalnızca dize değerine koyar ve dize değerini alır (new Gson()).toJson(myObject);ve fromJsonbunu nesnenize geri çevirmek için kullanırsınız .

Ancak nesneniz çok karmaşık değilse, ek yüke değmeyebilir ve bunun yerine nesnenin ayrı değerlerini iletmeyi düşünebilirsiniz.


19
FiXedd'in cevabı, harici kütüphaneleri kullanmadan aynı sorunu, çok daha tercih edilir bir şekilde çözdüğü için, hiç kimsenin sağladığım çözümden geçmesi için bir nedeni olmamalı (o zaman, habersiz,) fiXedd's brilliant solution)
David Hedlund

5
Bence bu doğru. Ayrıca, JSON, iş parçacığı için değil, istemci / sunucu için daha uygun bir protokoldür.
mobibob

16
Mutlaka kötü bir fikir değil, özellikle. Gson'un kullanımı, göndermek istediğiniz tüm nesneler için parcelable uygulamaktan çok daha basittir.
uvesten

7
iam benim app gson kullanarak bu gerçekten kolay ve güzel bir yoludur!
Lars

16
Güzel cevap, komple bir çözüm olacağını ancak String s = (new Gson().toJson(client));o zaman veCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk

155

Serileştirilebilir nesneyi niyet yoluyla gönderebilirsiniz

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
Parcelable nesnelerini de niyet yoluyla gönderebilirsiniz.
tony gil

6
"Serializable Android'de komik yavaş. Aslında pek çok durumda Borderline işe yaramaz." bakmak stackoverflow.com/questions/5550670/...
Seraphim en

etkinlik zaten çalışıyorsa, startActivity (i) yapması gerekir; ? Ben yapabilir demek etkinlik A çağrı etkinliği B ve o döner veri etkinlik A ? kafam karıştı mı?
Francisco Corrales Morales

3
@ Seraphim'in Performansı çok fazla nesneyi serileştiriyorsanız önemlidir, ancak kullanıcı bir nesneyi serileştirmenin 1 ms veya 10 ms sürdüğünü fark etmez. Ekstra bir niyet zaten Serializableama değilse Parcelable, bunu yapmak için nadiren uğraşmaya değer Parcelable.
Kevin Krumwiede

67

Bir uygulama içinde veri geçireceğinizi bildiğiniz durumlar için "globaller" kullanın (statik Sınıflar gibi)

İşte budur Dianne Hackborn : konuda söylemek zorunda - (bir Google Android Yazılım Mühendisi hackbod)

Etkinliklerin aynı süreçte yürütüldüğünü bildiğiniz durumlar için, verileri yalnızca globaller aracılığıyla paylaşabilirsiniz. Örneğin, bir küresel olabilir HashMap<String, WeakReference<MyInterpreterState>> ve yeni bir MyInterpreterState yaptığınız zaman bunun için benzersiz bir isim bulup karma haritasına koyabilirsiniz; bu durumu başka bir etkinliğe göndermek için, benzersiz adı karma haritaya koyun ve ikinci etkinlik başlatıldığında MyInterpreterState'i aldığı adla karma haritadan alabilir.


25
evet bu niyetleri kullanmamızı garip buldum ve sonra üst düzey bir mühendis bize sadece küreselleri verilerimiz için kullanmamızı söylüyor. Ama orada doğrudan atların ağzından.
Richard Le Mesurier

1
Buradaki zayıf reddetme çöp toplama kurbanı olmaz mı?
uLYsseus

1
@uLYsseus bunun bir fikir olduğunu düşünüyorum, aktivitelerde onlarla işiniz bittiğinde ... bu yüzden ilgili faaliyetler yok edildiğinde,
gc'ye

1
@RichardLeMesurier Aynı şeyi düşünüyordum, ancak daha sonra Dianne Hackborn'un yukarıda belirtilen Google Grupları yayınına baktım ve küresellerle ilgili tek sorunun örtük niyetleri kullanırken (paketinizin dışında bir etkinlik başlatabileceğini) ). Bu, Dianne'nin belirttiği gibi mantıklıdır, çünkü bu faaliyetlerin büyük olasılıkla kendilerine aktardığınız özel türler hakkında sıfır bilgisi olacaktır. Bunu okuduktan sonra, koşullar altında küresellerin neden bu kadar kötü bir rota olamayacağını netleştirdim ve başkalarının da merak etmesi durumunda paylaşacağımı anladım
BMB

niyetler, niyetin farklı bir bilgisayara aktarılabileceği bir noktaya kadar yeniden yapılandırıldı. açıkçası tek bir işleminiz varken hiçbir şey yapmanın iyi bir yolu değildir. sonuncusu, özellikle tasarımda oldukça şaşırtıcı olan niyetleri olan tasarım seçimlerini yaptı. iyi bir fikir olduklarında ısrar eden insanlar var, çünkü genellikle "google böyle söyledi".
Lassi Kinnunen

49

Sınıfınız Serializable veya Parcelable kullanmalıdır.

public class MY_CLASS implements Serializable

İşiniz bittiğinde putExtra'da bir nesne gönderebilirsiniz

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Ekstraları almak için yapmanız gereken sadece

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

Sınıfınız Parcelable özelliğini kullanıyorsa

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

Umarım yardımcı olur: D


6
Sınıfınız Serializableyanlış uygulamalıdır . Sınıf Parcelableörneğin uygulayabilir .
Marc Plano-Lesay

Parcelable ve Serializable @Kernald arasındaki fark nedir? işlem süresi açısından daha yavaş / en iyi uygulama falan değil mi?
Gumuruh

SerializableStandart bir Java arayüzü iken , ParcelableAndroid'e özgüdür. Performans açısından, Parcelable daha verimlidir: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay

35

Hızlı ihtiyaç için kısa cevap

1. Sınıfınızı Serileştirilebilir olarak uygulayın.

Eğer herhangi bir iç Dersiniz varsa bunları da Serileştirilebilir olarak uygulamayı unutmayın !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Nesnenizi Niyetin içine koyun

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. Ve nesnenizi diğer Etkinlik Sınıfında alın

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");


Aynı şeyi Parcelable arabirimini uygulayarak da elde edebilirsiniz. Parcelable arabiriminin, kod boyutu nedeniyle Serializable'a kıyasla uygulanması daha fazla zaman alır. Ancak Serileştirilebilir'den daha hızlı performans gösterir ve daha az kaynak kullanır.
Kwnstantinos Nikoloutsos

27

nesne sınıfınız uygulanırsa Serializable, başka bir şey yapmanız gerekmez, serileştirilebilir bir nesne iletebilirsiniz.
Ben bunu kullanıyorum.


24

sınıfınızda serileştirilebilir uygulama

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

        public void setName(String name) {
           this.name = name;
        }
}

O zaman bu nesneyi niyetle aktarabilirsiniz

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

ikinci etkinlikte int böyle veriler alabilirsiniz

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

Ancak veriler büyüdüğünde, bu yöntem yavaş olacaktır.


16

Diğer sınıflardaki veya Etkinlikteki değişkenlere veya nesnelere erişmenin birkaç yolu vardır.

A. Veritabanı

B. paylaşılan tercihler.

C. Nesne serileştirme.

D. Ortak verileri tutabilen bir sınıf, size bağlı olan Ortak Yardımcı Programlar olarak adlandırılabilir.

E. Verilerin Amaçlar ve Parcelable Interface'den geçirilmesi.

Proje gereksinimlerinize bağlıdır.

A. Veritabanı

SQLite, Android'e gömülü bir Açık Kaynak Veritabanıdır. SQLite, SQL sözdizimi, işlemler ve hazırlanmış ifadeler gibi standart ilişkisel veritabanı özelliklerini destekler.

Eğiticiler - http://www.vogella.com/articles/AndroidSQLite/article.html

B. Paylaşılan Tercihler

Kullanıcı adını saklamak istediğinizi varsayalım. Şimdi Anahtar Kullanıcı Adı, Değer Değeri olmak üzere iki şey olacaktır .

Nasıl saklanır

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

PutString (), putBoolean (), putInt (), putFloat (), putLong () kullanarak istediğiniz dtatype'i kaydedebilirsiniz.

Nasıl getirilir?

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

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

C. Nesne Dizileştirme

Nesne serlizasyonu, bir nesne durumunu ağ üzerinden göndermek üzere kaydetmek istiyorsak veya amacınız için de kullanabilirsiniz.

Java fasulyesi kullanın ve tarlalarından biri olarak saklayın ve bunun için alıcıları ve ayarlayıcıyı kullanın

JavaBeans, özellikleri olan Java sınıflarıdır. Özellikleri özel yönetim ortamı değişkenleri olarak düşünün. Özel olduklarından, sınıflarının dışından erişebilmelerinin tek yolu sınıftaki yöntemlerdir. Bir özelliğin değerini değiştiren yöntemlere setter yöntemleri denir ve bir özelliğin değerini alan yöntemlere getter yöntemleri denir.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

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


}

Kullanarak posta yönteminizdeki değişkeni ayarlama

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

Sonra bu nesneyi serileştirmek ve diğer sınıfınızda bu nesnenin serisini kaldırmak için Serialzation nesnesini kullanın.

Serileştirmede bir nesne, nesnenin verilerini ve nesnenin türü ve nesnede depolanan veri türleri hakkında bilgi içeren bir bayt dizisi olarak temsil edilebilir.

Serileştirilmiş bir nesne bir dosyaya yazıldıktan sonra, dosyadan okunabilir ve serileştirilebilir, yani nesneyi ve verilerini temsil eden tür bilgisi ve baytlar, nesneyi bellekteki yeniden oluşturmak için kullanılabilir.

Bunun için eğitim istiyorsanız bu bağlantıya bakın

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

Diğer sınıflarda değişken alın

D. Ortak Hizmetler

Projenizde sıklıkla ihtiyaç duyduğunuz ortak verileri içerebilen kendi kendinize bir sınıf oluşturabilirsiniz.

Örneklem

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Verilerin Amaçlardan Geçirilmesi

Bu veri aktarma seçeneği için lütfen bu eğiticiye başvurun.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


(E) 'de Intents'ten veri aktarımı hakkında bahsettiğiniz iyi bir öğretici.
remrick

16

Bunu yapmak için android BUNDLE kullanabilirsiniz.

Sınıfınızdan aşağıdaki gibi bir Paket oluşturun:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

Ardından bu paketi INTENT ile geçirin. Artık sınıf nesnenizi aşağıdaki gibi bir paket geçirerek yeniden oluşturabilirsiniz

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

Özel sınıfınızda bunu bildirin ve kullanın.


1
Doğrudan Parcelable uygulamasına tercih edilir, IMHO. Bundle kendi başına Parcelable uygular, böylece yine de performans kazancı elde edersiniz ve bunu kendiniz uygularken tüm sorunlardan kaçınırsınız. Bunun yerine, yalnızca siparişe dayanmaktan çok daha sağlam olan verileri depolamak ve almak için anahtar / değer çiftlerini kullanabilirsiniz.
Risadinha

Parcelable benim için karmaşık görünüyor, yukarıdaki cevabımda nesnenin üzerindeki sınıftan toBundle yöntemini kullanıyorum, böylece nesne demete dönüştürülüyor ve sonra paketi sınıf nesnesine dönüştürmek için yapıcıyı kullanabiliriz.
om252345

Bu çözüm yalnızca tek bir nesneyi bir niyetten geçiriyorsanız uygulanabilir.
TheIT

Json gibi ama json hafif olduğunu düşünüyorum.
David

Onu aldığımda nesne aynı nesne mi yoksa kopya mı olacak?
Markus

15

Parcelable yardım için teşekkürler ama bir tane daha isteğe bağlı çözüm buldum

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

Etkinlik 1'de

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

Etkinlik 2'de Veri Alın

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
iyi bir cevap, ama Kodlama Standartlarınızı artırın ... +1 ama yarışmada Serializable getirmek için olsa da Parseller çok daha hızlı ...
Amit

13

Etkinlikler arasında nesne göndermek için Gson'u çok güçlü ve basit API'si ile kullanıyorum,

Misal

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

Göndermek istediğiniz nesnelere eklediğiniz 2 işlev

kullanım

Nesneyi A'dan B'ye Gönder

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

B'de al

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

Neredeyse yaptığım her projede kullanıyorum ve performans sorunlarım yok.


Teşekkürler, bu bana saatler süren aşırı komplikasyonu kurtardı.
Hristo Stoyanov

10

Aynı sorunla mücadele ettim. Statik bir sınıf kullanarak, HashMap'te istediğim verileri depolayarak çözdüm. Üstte gizli veri taşıma ve veri temizleme yapmak için bir onDrearoy yöntemleri geçersiz kılınmış standart Activity sınıfının bir uzantısını kullanın. Bazı saçma ayarların değiştirilmesi gerekir, örneğin yönlendirme-işleme.

Ek Açıklama: Genel bir nesnenin başka bir Etkinliğe geçmesini sağlamak kıçtaki acıdır. Kendini dizinden vurmak ve 100 metre kazanmayı ummak gibi. "Parcable" yeterli bir ikame değildir. Beni güldürüyor ... Bu arayüzü teknolojisiz API'ma uygulamak istemiyorum, çünkü daha az yeni bir Katman tanıtmak istiyorum ... Nasıl olabilir, mobil programlamada şu ana kadar uzaktayız modern paradigma ...


9

İlk Faaliyetinizde:

intent.putExtra("myTag", yourObject);

Ve ikincisinde:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

Özel nesnenizi Serializable yapmayı unutmayın:

public class myCustomObject implements Serializable {
...
}

Parcelable Serializable daha iyidir! Serializable'ı Android kodunuzda kullanmaktan kaçının!
Filipe Brito

7

Bunu yapmanın başka bir yolu da Applicationnesneyi kullanmaktır (android.app.Application). Bunu AndroidManifest.xmldosyanızda şu şekilde tanımlarsınız :

<application
    android:name=".MyApplication"
    ...

Daha sonra bunu herhangi bir etkinlikten çağırabilir ve nesneyi Applicationsınıfa kaydedebilirsiniz .

FirstActivity'de:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

SecondActivity'de şunları yapın:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

Uygulama düzeyinde kapsamı olan nesneleriniz varsa, yani bunların uygulama boyunca kullanılması gerektiğinde kullanışlıdır. ParcelableEğer kapsamı sınırlıdır veya eğer nesne kapsamı üzerinde tam kontrol istiyorsunuz eğer yöntem daha iyi hala.

Ancak bu Intentstamamen kullanılmasını önler . Size uygun olup olmadıklarını bilmiyorum. Bunu kullandığım başka bir yol int, nesnelerin tanımlayıcılarının amaçlarla gönderilmesi ve Applicationnesnedeki Haritalar'da sahip olduğum nesneleri almasıdır .


1
Bu nesneler değişken olabileceği için, uygulamanın yaşam döngüsü boyunca statik nesne bahsedersen senin çalışabilir, ancak bazı zamanlar biz ya da öylesine webservice kullanılarak oluşturulan olabilir nesneleri passiing gerek şeyler yapmak için doğru bir yol değildir stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri

MapNesnelerin bir tanımlayıcı kullanılarak depolandığı ve alındığı bir uygulama kapsamına sahip olarak web hizmetlerinden oluşturulan nesnelerle başarılı bir şekilde kullandım. Bu yaklaşımla ilgili tek gerçek sorun, Android'in bir süre sonra belleği temizlemesidir, bu nedenle onResume'nizde null'ları kontrol etmeniz gerekir (bence amaçlarda iletilen Nesneler kalıcıdır, ancak emin değilim). Bunun dışında bunu önemli ölçüde düşük olarak görmüyorum.
Saad Farooq

Bu en iyi cevap. Farklı etkinliklerin aynı veri modeline nasıl referans verebileceğini gösterir. Bunu keşfetmem çok uzun sürdü!
Markus

6

sınıf modelinizde (Object) Serializable uygulamasını uygulayın, örneğin:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

ve ilk Etkinliğiniz

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

ve ikinci Etkinliğiniz (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

iyi şanslar!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

Verilerin iletilmesi:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

Verileri alma:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

bulduğum en kolay çözüm .. alıcılar ayarlayıcıları ile statik veri üyeleri ile bir sınıf oluşturmaktır.

bir etkinlikten ayarlayın ve o nesnenin başka bir etkinliğinden alın.

aktivite A

mytestclass.staticfunctionSet("","",""..etc.);

aktivite b

mytestclass obj= mytestclass.staticfunctionGet();

1
ya da geçmek istediğiniz başka bir etkinliğe geçmek için creata serileştirilebilir sınıf.
UMAR

9
Sadece büyük şişman nesneler koymamayı unutmayın. Bu nesnenin ömrü uygulamanın ömrüyle aynı olacaktır. Ve asla görüntüleme saklamayın. Bu yöntem ayrıca bellek sızıntılarını da garanti eder.
Reno

1
Bu yanıt faydalıdır ancak bellek ve kaynak optimizasyonu açısından daha iyi bir çözüm değildir
Atul Bhardwaj

1
Bu, küresel değişkenler tanıtarak OOP ilkelerini ihlal eder. Hangi durumda olduklarını, ayarlanıp ayarlanmadıklarını asla bilemezsiniz, birçok iplik tarafından kullanılırlar ve bu karmaşıklıkla uğraşmak zorundasınız. Genellikle iyi bir bellek sızıntısıdır, çünkü bu değişkenlerin ne zaman serbest bırakılacağını bile bilmiyorsunuz. Uygulamanın farklı modülleri arasında sert doğrudan bağlantı sağladığını söylememek gerekir.
afrish

2
O NE LAN? Diğer iki cevap çok daha üstün.
IcyFlame

4

sınıf türünüzdeki nesneleri iletmek ve almak için putExtra (Serializable ..) ve getSerializableExtra () yöntemlerini kullanabilirsiniz; Serializable sınıfınızı işaretlemeniz ve tüm üye değişkenlerinizin serileştirilebilir olduğundan emin olmanız gerekir ...


4

Android Uygulaması Oluşturun

Dosya >> Yeni >> Android Uygulaması

Proje adını girin: android-pass-object-activity

Pakcage: com.hmkcode.android

Diğer defualt seçimlerini koru, Bitir'e ulaşana kadar İleri'ye git

Uygulamayı oluşturmaya başlamadan önce, bir aktiviteden diğerine nesne göndermek için kullanacağımız POJO sınıfı “Kişi” yaratmamız gerekiyor. Sınıfın Serializable arabirimi uyguladığına dikkat edin.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

İki Etkinlik İçin İki Düzen

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

İki Etkinlik Sınıfı

1) ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

Google'ın Gson kütüphanesini kullanarak nesneyi başka bir etkinliğe geçirebilirsiniz.Genellikle json dizesi biçiminde nesneyi dönüştüreceğiz ve başka bir etkinliğe geçtikten sonra tekrar böyle bir nesneye dönüştüreceğiz

Bunun gibi bir fasulye sınıfı düşünün

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Örnek sınıf nesnesini geçirmemiz gerekiyor

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

Okuma için NextActivity'de ters işlemi yapmamız gerekiyor

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

Bu bağımlılığı dereceye ekle

compile 'com.google.code.gson:gson:2.6.2'

3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);

3

Bunun geç olduğunu biliyorum ama çok basit. Tüm yapmanız gereken, sınıfınızın Serializable

public class MyClass implements Serializable{

}

o zaman böyle bir niyete geçebilirsin

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

Bunu elde etmek için çağırırsın

MyClass objec=(MyClass)intent.getExtra("theString");

2

Yine de, model katmanınıza ağ geçidi görevi gören tek bir sınıfınız (fx Hizmeti) varsa, bu sınıfta bunun için alıcılar ve ayarlayıcılar içeren bir değişken bulunarak çözülebilir.

Etkinlik 1'de:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

Etkinlik 2'de:

private Service service;
private Order order;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quality);

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

Serviste:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

Bu çözüm, söz konusu nesnenin serileştirilmesini veya başka bir "paketlenmesini" gerektirmez. Ancak yine de bu tür bir mimari kullanıyorsanız faydalı olacaktır.


Bu yaklaşımın dezavantajları nelerdir? Çok mantıklı ve zayıf görünüyor. Her zaman bunu yapmaman gerektiğini okudum ama neyin yanlış gidebileceğiyle ilgili hiçbir zaman iyi bir açıklama alamadım.
Markus

Artık yorumumu düzenleyemediğim için: Bu, kopya yerine bir nesneye başvuru yapmak için tek olası çözüm değil mi? Aynı kopyayı almam gerekiyor, kopya değil!
Markus

Bence bu yüksek bağlantı nedeniyle cesaretini kırdı. Ama evet, görebildiğim kadarıyla, gerçek nesneye ihtiyacınız varsa bu yaklaşım en uygun olanı. Programlamada her zaman olduğu gibi, istediğinizi yapabilirsiniz, sadece dikkatli bir şekilde yapmak istersiniz. Bu çözüm benim için çalıştı ve ben zaten o mimariyi kullandığım için tercih ederim.
Kitalda

Aslında Application sınıfını genişletip veri modelimi orada sakladım. Amaçlarda yalnızca orijinal nesneyi Application sınıfından almak için kullanılabilecek veri nesnelerinin kimliğini aktardım. Ayrıca genişletilmiş uygulama sınıfı, standart bir dinleyici kavramı aracılığıyla değişirse veri modelini kullanan tüm nesnelere bildirim gönderir. Bu tüm uygulama üzerinde bir datamodel paylaşmak için gereken sadece benim durumuma uygun biliyorum ama bu durumda onun mükemmel ve statik sınıflar ve alanlar da gerekli!
Markus

2

Nesneleri parsellemek için IMHO çok kolay yolu. Parcelable yapmak istediğiniz nesnenin üzerine bir ek açıklama etiketi eklemeniz yeterlidir.

Kütüphaneden bir örnek https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

İlk olarak Parcelable'ı sınıfınıza uygulayın. Sonra böyle bir nesne geçirin.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

Paket dizesi gerekli değildir, yalnızca dizenin her iki Etkinlikte de aynı olması gerekir

REFERANS


2

Bundle Nesnesi aracılığıyla bu etkinlik geçirme parametrelerinden başka bir etkinlik başlatma

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

Başka bir etkinliğe erişme (YourActivity)

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

Bu basit tür veri türü için uygundur. Ama u aktivite arasında karmaşık veri geçmek istiyorsanız u önce serileştirmek gerekir.

İşte Çalışan Modelimiz var

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

    getters...
    setters...
}

Bunun gibi karmaşık verileri serileştirmek için google tarafından sağlanan Gson lib'i kullanabilirsiniz

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

2

Koltin bölgesinde

Build.gradle klasörüne kotlin uzantısı ekleyin.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Ardından veri sınıfınızı böyle oluşturun.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

Nesneyi Niyetle Geç

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

Niyetle nesne edinin

val sample = intent.getParcelableExtra("id")

Hala deneysel mi?
ShadeToD

2

En kolay ve java yapmanın yolu: pojo / model sınıfınıza serileştirilebilir uygulamak

Performans görünümü için Android için önerilir: modeli parcelable


1

En basiti, öğenin bir dize olduğu yerde aşağıdakileri kullanmaktır:

intent.putextra("selected_item",item)

Almak için:

String name = data.getStringExtra("selected_item");

3
onun sadece dize, tamsayı ve vb için ama ben nesne istiyorum ve statik nesne kullanarak sadece mümkün.
UMAR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.