Android'de bir etkinlikten diğerine nesne nasıl aktarılır


779

Müşteri sınıfımın bir nesnesini birinden gönderip diğerinde Activitygörüntülemeye çalışıyorum Activity.

Müşteri sınıfı kodu:

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

Nesnesini birinden diğerine göndermek Activityve sonra verileri diğerinde görüntülemek istiyorum Activity.

Bunu nasıl başarabilirim?


1
muhtemelen kabul edilen cevabı kitlesel görüş ışığında değiştirmelisiniz.
Rohit Vipin Mathews

Nesneyi Pacelable veya Serializable olarak ayarladım, ancak başka değişkenler eklediğimde, her şeyi Pacelable veya Serializable için alıp ayarlamak için işlevlere eklemeliyim. bu yüzden faaliyetleri ve parçaları arasında aktarmak için DataCache yaptım. github.com/kimkevin/AndroidDataCache Nesneyi aktarmak çok kolay.
kimkevin

Yanıtlar:


886

Bir seçenek, özel sınıfınızın Serializablearabirimi uygulamasına izin vermek olabilir ve daha sonra yöntemin putExtra(Serializable..)varyantını kullanarak fazladan amaç örneklerini iletebilirsiniz Intent#putExtra().

Sözde kod :

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

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

Not: Ana özel sınıfınızın her iç içe sınıfının, serileştirme istisnalarını önlemek için Seri Hale Getirilebilir arabirim uyguladığından emin olun. Örneğin:

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

126
@OD: Savunmamda bunun en iyi seçenek olduğunu asla söylemedim; OP sadece alternatif istedi ve ben bir tane önerdi. Yine de teşekkürler.
Samuh

83
Serializable neden iyi bir seçenek değil? Bu iyi bilinen bir arayüz, insanların sınıflarının zaten uygulayabilme şansı var (örneğin, ArrayList zaten Serializable). Neden bir nesneden diğerine geçmek için ekstra kod eklemek için veri nesnelerinizi değiştirmelisiniz? Kötü bir tasarım gibi görünüyor. Bir düzeyde performans etkisi olabileceğini hayal edebiliyorum, ancak vakaların% 99'unda insanların az miktarda veri geçtiğini ve umursamayacaklarını düşünüyorum. Daha basit ve taşınabilir bazen de daha iyidir.
Nate

16
@Sander: Bu yanıt ( stackoverflow.com/questions/2139134/… ) yanlış mı? Parcelable IS'nin bu amaç için özel olarak tasarlandığını (ve daha hızlı olduğunu Serializable) söylüyor . Ben kafam karıştı.
Slauma

41
Parcelablehız için iyi olabilir, ancak uygulanması karmaşıktır. Etkinlikler arasında geçmeniz gereken 8 nesneniz varsa, her birini yapacak Parcelablemısınız? Bunun Serializableyerine kullanmak daha mantıklı olacaktır . Uyguladığınızda Parcelable, sınıfa çok fazla kod eklemeniz ve alanları çok özel bir şekilde sıralamanız gerekir; Serializableyapmazsın. Sonuçta, sanırım kaç tane nesneyi geçtiğinize ve ne yapmaya çalıştığınıza bağlı.
BlackHatSamurai

15
Serializablestandart bir Java arayüzüdür. Arayüzü uygulayarak seri hale getirilebilir bir sınıfı işaretlersiniz ve Java belirli durumlarda otomatik olarak serileştirir. ParcelableSerileştirmeyi kendiniz uyguladığınız Android'e özgü bir arayüzdür. Serializable'dan çok daha verimli olmak ve varsayılan Java serileştirme şemasıyla ilgili bazı problemleri aşmak için yaratıldı
Gaurav Arora

311

Serializable ile sınıfınızı uygulayın. Bunun varlık sınıfınız olduğunu varsayalım:

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

deneX etkinliğinden çağırılan nesneyi Y etkinliğine gönderiyoruz . X etkinliğinde bir yerde;

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

Y etkinliğinde nesneyi alıyoruz.

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

Bu kadar.


1
Benim için gerçekten çok yardımcı oldu. Teşekkürler ... Ancak iletilen nesneyi alırken, sözdizimi [Deneme dene = (Deneme) i.getSerializableExtra ("sampleObject") olmalıdır; ] ... Bu mu ???
JibW

1
@ MustafaGüven Ama classCastException: java.lang.Longbunu yaparak alıyorum . Nedenini açıklayabilir misiniz?
Shajeel Afzal

Cevabımla hiçbir ilişkisi yok. Aldığınız çok farklı bir şey. Kodlarınızı paylaşabilir misiniz?
Mustafa Güven

1
Serileştirilebilir büyük POJO'lar için çok yavaş. Otobüs kullanmak çok daha iyi bir modeldir.
Steven Mark Ford

1
(Serializable)Nesneye neden önek eklemeliyim ?
Alston

123
  • Global statik değişkenleri kullanmak iyi bir yazılım mühendisliği uygulaması değildir.
  • Bir nesnenin alanlarını ilkel veri türlerine dönüştürmek telaşlı bir iş olabilir .
  • Kullanılması serializable Tamam, ama performans açısından verimli değildir Android platformu üzerinde.
  • Parcelable, Android için özel olarak tasarlanmıştır ve kullanmalısınız. Basit bir örnek: Android etkinlikleri arasında özel nesneler geçirme

Bu siteyi kullanarak sınıfınız için Parcelable kodu oluşturabilirsiniz .


4
Nesnem iç içe Arraylist içeriyorsa ne olur?
Dr. aNdRO

10
Belki de bir kişi gerçekten bir tuz imo tanesi ile `` performans '' almalıdır. Bu uygulama fiyatına gelirse, ParcelablePOJO sınıflarımı Android agnostik ve kullanımı tercih ederim Serializable.
VH-NZZ

Parcelable kullanmanız gerektiğini kabul etmiyorum. Basit bir BUS deseni çalışma zamanında çok daha verimlidir ve çok fazla dev zaman tasarrufu sağlar.
Steven Mark Ford

15
Bu karşılaştırmaya göre bitbucket.org/afrishman/androidserializationtest Serializable'için çok daha hızlı Parcelable fazla. Lütfen bu 5 yaşındaki Parcelable hakkındaki saçmalıkları paylaşmayı bırakın.
Mart'ta 15

7
Global statik değişkenler "iyi yazılım mühendisliği uygulaması değil" nasıl? Tek bir önbellek ve / veya veri ızgarası gibi bir şey yapabilir, ardından kimlik veya benzerlerini geçebilirsiniz. Java'da başvuruları ilettiğinizde, genel olarak aynı nesneyi işaret ettikleri için bir anlamda genel statik değişkenleri kullanırsınız.
breakline

112

Nesnenizi JSON'a dönüştürmek ve niyetten geçirmek için gson kullanın . Yeni Etkinlik'te JSON'u bir nesneye dönüştürün.

Bunu build.gradle, bağımlılıklarınıza ekleyin

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

Etkinliğinizde, nesneyi json-string'e dönüştürün:

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

Alma Etkinliğinizde, json dizesini orijinal nesneye geri dönüştürün:

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

İçin KOTLIN oldukça aynı şey

Verileri geçirin

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

Verileri alın

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

3
Bu bir aşırıya kaçma, gson, json'a sadece dize serileştirmenin bir türüdür, Serializable veya Paracable'ı uygulamak daha iyidir.
James Roeiter

14
Bunu işleyen bir kütüphane (gson) kullanabiliyorsanız, her nesnede ve her projede (zaman kaybı) serileştirilmeye gerek yoktur. Ve aşırı dolu hakkında, orada çift ve dört çekirdekli telefonlar var, bu cevap fikrini takip eden bir listeyi bile ele alabilirler.
sagits

4
Ayrıca gson kullanmanızı tavsiye ederim çünkü gson yukarıdakilere ek olarak arraylistleri serileştirebilir.
nurgasemetey

4
Bu harika! Benim durumumda, nesnelerin serileştirilemez veya parcelable yok uygulamak bir kütüphane kullanıyorum. Yani bu benim tek seçenek afaik
Chad Bingham

2
Bu "en iyi" seçenektir. Bazı sınıflar o kadar basit ki, serileştirilebilirlik uygulayarak uygulamalarını aşırı karmaşıklaştırmanıza gerek yok
Ojonugwa Jude Ochalifu

98

Bir etkinliği çağırırken

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

ToClass.java içerisinde etkinliği

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

Lütfen müşteri sınıfının parcelable uygulandığından emin olun

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

Adhavan, bir sorum var. İlk Intent sınıfını oluşturduğunuzda, ilk bağımsız değişken olarak fromClass.this komutunu iletirsiniz. Bu nesneyi alan aktivite sınıfında almanın bir yolu var mı?
newman

1
Miliu, fromClass fr = (fromClass) getParent (); ihtiyacın olan bu mu?
Reklamlar

Adhava, bunu gerçekten yaptım ama fr boş. Neden olduğu hakkında bir fikrin var mı?
newman

miliu, lütfen içine girebilmemiz için istisna izini paylaş.
Reklamlar

Parcelable, çok sayıda gereksiz kazan plakası koduna sahiptir ve açıkçası zaman kaybıdır. Aksine bir otobüs kullanın. Aşağıdaki yazıma bakın.
Steven Mark Ford

89

Deneyimlerime göre, her biri dezavantajları ve avantajları olan üç ana çözüm var:

  1. Parcelable Uygulanması

  2. Serializable Uygulanması

  3. Bir çeşit hafif olay otobüsü kütüphanesi kullanma (örneğin, Greenrobot'un EventBus'u veya Square's Otto)

Parcelable - hızlı ve Android standardı, ancak çok sayıda kazan plakası kodu vardır ve değerleri niyetten çekerken referans olarak sabit kodlu dizeler gerektirir (kuvvetle yazılmamış).

Serializable - sıfıra yakın kazan plakası, ancak en yavaş yaklaşımdır ve aynı zamanda değerleri niyetten çekerken sabit kodlu dizeler gerektirir (kuvvetle yazılmamış).

Olay Veri Yolu - sıfır kaynatma plakası, en hızlı yaklaşım ve sabit kodlu dizeler gerektirmez, ancak ek bir bağımlılık gerektirir (genellikle hafif olmasına rağmen, ~ 40 KB)

Verimlilik ölçütleri de dahil olmak üzere bu üç yaklaşım etrafında çok ayrıntılı bir karşılaştırma yaptım.


4
Makalenin bağlantısı öldü. Hala webarchive'da
OlivierH

Bağlantının
kesilmiş

Olay Veri Yolu kullanım sorunu, hedef Döndürme nedeniyle yeniden yaratıldığı zamandır. Bu durumda, hedef Etkinlik geçilen nesneye erişemez, çünkü bu nesne daha önce çağrı ile veri yolundan tüketilir.
JuliuszJ

1
Parcelable en hızlısıdır ve bu jeneratörle ( parcelabler.com ), sınıfınızı yapıştırabilir ve kodu sizin için oluşturabilirsiniz. Basit.
ByWaleed

1
@ByWaleed ... Kesinlikle katılıyorum, her zaman bu siteyi kullanıyorum, herhangi bir hassel içermeyen şeyler yapıyor. Ancak, başka bir nesneden oluşan bir POJO kullanmaya çalıştığımda birçok başarısız denemem oldu. Nedense onun koymak gerçekten çalışmıyor.
Yo Apps

42

Basit ve zarif bir yöntem buldum:

  • Parcelable
  • Serializeable YOK
  • Statik Alan YOK
  • Etkinlik Otobüsü Yok

Yöntem 1

İlk etkinliğin kodu:

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

İkinci etkinliğin kodu:

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

sen bulacaksın objSentve objReceivedaynıhashCode , bu yüzden aynı.

Ama neden bir java nesnesini bu şekilde aktarabiliriz?

Aslında, android bağlayıcı java nesnesi için global JNI referansı oluşturacak ve bu java nesnesi için referans olmadığında bu global JNI referansını serbest bırakacaktır. binder bu global JNI başvurusunu Binder nesnesine kaydeder.

* DİKKAT: bu yöntem SADECE iki işlem aynı işlemde çalışmadığı sürece çalışır, aksi takdirde ClassCastException (ObjectWrapperForBinder) getIntent (). GetExtras (). GetBinder ("object_value") *

class ObjectWrapperForBinder tanımı

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Yöntem 2

  • gönderen için,
    1. java nesnenizi JNI genel başvuru tablosuna eklemek için özel yerel yöntemi kullanın (JNIEnv :: NewGlobalRef aracılığıyla)
    2. dönüş tamsayısını (aslında, bir işaretçi olan JNIEnv :: NewGlobalRef dönüş jobject'i, int'e güvenli bir şekilde atabiliriz) niyetinize (Intent :: putExtra aracılığıyla)
  • alıcı için
    1. Intent'ten tamsayı alın (Intent :: getInt aracılığıyla)
    2. java nesnenizi JNI genel başvuru tablosundan geri yüklemek için özel yerel yöntem kullanın (JNIEnv :: NewLocalRef aracılığıyla)
    3. JNI genel referans tablosundan öğeyi kaldır (JNIEnv :: DeleteGlobalRef aracılığıyla),

Ancak Yöntem 2'nin küçük ama ciddi bir sorunu vardır, alıcı java nesnesini geri yükleyemezse (örneğin, java nesnesini geri yüklemeden önce bir istisna oluşur veya alıcı Etkinliği hiç mevcut değilse), java nesnesi bir yetim veya bellek sızıntısı, Yöntem 1'de bu sorun yok, çünkü android bağlayıcı bu istisnayı ele alacak

Yöntem 3

Java nesnesini uzaktan çağırmak için, java nesnesini tanımlamak için bir veri sözleşmesi / arabirimi oluşturacağız, aidl dosyasını kullanacağız

IDataContract.aidl

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

İlk etkinliğin kodu

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

İkinci etkinliğin kodu:

ikinci etkinliğin başka bir işlemde çalıştığından emin olmak için AndroidManifest.xml dosyasında android: process özniteliğini boş olmayan bir işlem adına değiştirin

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

Bu şekilde, farklı işlemlerde çalışsalar bile, iki etkinlik arasında bir arabirim geçirebilir ve arabirim yöntemini uzaktan çağırabiliriz

Yöntem 4

yöntem 3 yeterince basit görünmüyor çünkü bir aidl arabirimi uygulamalıyız. Sadece basit bir görev yapmak istiyorsanız ve yöntem dönüş değeri gereksizse, android.os.Messenger'ı kullanabiliriz.

İlk faaliyetin kodu (gönderen):

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

İkinci etkinliğin kodu (alıcı):

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

    }
}

Tüm Messenger.send, bir İşleyicide zaman uyumsuz ve sıralı olarak yürütülür.

Aslında, android.os.Messenger da bir aidl arayüzüdür, android kaynak kodunuz varsa, IMessenger.aidl adlı bir dosya bulabilirsiniz

package android.os;

import android.os.Message;

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

Maalesef cevabınızda bağlayıcı olduğunu görmedim, cevabınızın da çok zarif olduğunu hissediyorum.
SkidRunner

Vay be .... Bu adamın 1. yöntemi muazzam ..... İyi çalışan çok büyük / büyük boyutlu nesneler olduğunda
karan

Ben birinci yöntemi kullanıyorum. Teşekkürler;
ShweLiam

ObjectWrapperForBinder yöntemi için çok teşekkürler, gerçekten yardımcı oluyor!
Vladimir Tolstikov

40

Ayrıca nesnenin verilerini geçici Dizeler ve ints'a yazıp etkinliğe aktarabilirsiniz. Tabii ki, bu şekilde verileri taşıyabilirsiniz, ancak nesnenin kendisini değil.

Ancak, yalnızca bunları görüntülemek ve nesneyi başka bir yöntemde veya bunun gibi bir şeyde kullanmak istemiyorsanız, yeterli olmalıdır. Sadece başka bir etkinlikte bir nesneden veri görüntülemek için aynı şekilde yaptım.

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

Onları temp ivars yerine doğrudan da geçirebilirsiniz, ama bence bu daha açık. Ayrıca, geçici ivarları GarbageCollector tarafından daha erken temizlenecek şekilde null olarak ayarlayabilirsiniz.

İyi şanslar!

Yan notta: kendi yazdırma yönteminizi yazmak yerine toString () öğesini geçersiz kılın.

Aşağıdaki yorumlarda belirtildiği gibi, verilerinizi başka bir etkinlikte bu şekilde elde edersiniz:

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

9
ile verilerinizi tekrar geri alın: String fName = getIntent (). getExtras (). getInt ("fname");
Alister

2
Verileri geri almak için: Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
Eric Leschinski

1
Bu büyük POJO'lar için çabucak olanaksız hale gelebilir. Aksine bir otobüs kullanın. Aşağıdaki yazıma bakın.
Steven Mark Ford

cevabımda bahsettiğim gibi, bu nesnenin kendisine değil, sadece bazı değerlerine ihtiyaç duyduğunuz basit kullanımlar içindir. Karmaşık kullanımlar için bir soslution olmak söz konusu değildir.
MJB

1
İyi bir fikir tek bir nesneyi geçmek için, ama benim nesne bilinmeyen bir dizi geçirmeye çalışıyorum. Belki çözümünüz nesne dizilerini geçmek için değildir.
Muhammed Saqib

25

Geçici nesneleri tutan tek bir yardımcı sınıf yaptım.

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

Nesnelerinizi Intent içine koymak yerine IntentHelper kullanın:

IntentHelper.addObjectForKey(obj, "key");

Yeni Etkinliğinizin içinde nesneyi alabilirsiniz:

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

Yüklendikten sonra gereksiz referansları önlemek için nesnenin kaldırıldığını unutmayın.


1
İyi bir fikir! Ayrıca ek bir sınıf ObjectContainer {Object, obj; boole kalıcı; ....} Fikir şu ki, nesneyi kalıcı tutmanız ve get dediğimizde kaldırmamanız durumunda add metodunda bir boolean iletebilirsiniz. Bazı küresel nesnelerin korunmasına yardımcı olacaktır. Gibi açık bir bluetooth bağlantısı vb.
Olabilir

1
Sevimli ama tekerleği yeniden icat etme. Otobüs deseni zarif ve daha güçlü. Aşağıdaki yazıma bakın.
Steven Mark Ford

@StevenMarkFord bu yüzden Bus kalıbı bu güne kadar hala geçerli mi? Etkinlikler arasındaki verilere erişme gibi bir kod ile bir kod tabanı geliştirmeye çalışıyorum: BookActivity.getInstance().recommendationResponseiçindeRoomsActivity
Woppi

Alıcı Etkinlik yeniden oluşturulduğunda (örn. Ekran döndürmede) objolur null. Bundan kaçınmak objiçin, tekrar almak için bir yerde saklanmalıdır. Gerçekten de Json çözümü nesne verilerini Niyette saklar.
Salvador

25

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 Ortak Yardımcı Programlar olarak adlandırılabilir. O size bağlı.

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

Proje gereksinimlerinize bağlıdır.

A. Veritabanı

SQLite , Android'e yerleştirilmiş açık kaynaklı bir veritabanıdır. SQLite, SQL sözdizimi, işlemler ve hazırlanmış ifadeler gibi standart ilişkisel veritabanı özelliklerini destekler.

Öğreticiler

B. Paylaşılan tercihler

Kullanıcı adını saklamak istediğinizi varsayalım. Şimdi iki şey olacak, önemli bir kullanıcı adı, değer değeri.

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 () ve 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 serileştirme

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

Java fasulye kullanın ve onun alanlarından biri olarak saklayın ve bunun için getters ve setter 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 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 nesne serialzation 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 şu adrese başvurun:

D. Ortak Hizmetler

Projenizde sıkça ihtiyaç duyduğunuz ortak verileri içerebilecek bir sınıfı kendiniz yapabilirsiniz.

Örneklem

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Verilerin niyetlerden geçirilmesi

Bu veri aktarma seçeneği için Parcelable sınıflarını kullanarak Etkinlikler arasında geçiş yapmak için lütfen Android - Parsel verisine bakın .


22

Kendi sınıfınızı Customeraşağıdaki gibi oluşturun :

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

}

Senin içinde onCreate()yöntemle

@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 xyz activitysınıfında aşağıdaki kodu kullanmanız gerekir:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());

..Cust obj koymak ve "class" almak için anahtar olarak "bundle" geçiyor kodunuzu kontrol edin .. pls pls "class" veya "bundle" bir anahtar kullanın ..
AK Joshi

Karşılaştığım Hata: Ayrıştırılabilir IOException serileştirilebilir nesne yazma ile karşılaştı
Arul Mani

15

En iyi yol, uygulamanızda 'Müşteri' türünde statik bir değişkeni (sizin durumunuzda) barındıracak bir sınıfa (Kontrol denir) sahip olmaktır. Etkinlik A'nızda değişkeni başlatın.

Örneğin:

Control.Customer = CustomerClass;

Ardından Etkinlik B'ye gidin ve Kontrol sınıfından getirin. Değişkeni kullandıktan sonra bir boş değer atamayı unutmayın, aksi takdirde bellek boşa gider.


4
@aez Çünkü tasarım açısından özensizdir ve Niyet başka bir süreçte olursa korkunç bir şekilde kırılacaktır.

7
Uygulamanızı B Etkinliğine geri döndürdüğünüzde sorunlarla karşılaşırsınız. Çünkü Etkinlik Android tarafından öldürülebilir ve nesne kaydedilmez.
Ryan R

15
public class MyClass implements Serializable{
    Here is your instance variable
}

Şimdi startActivity'de bu sınıfın nesnesini iletmek istiyorsunuz. Sadece şunu kullanın:

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

MyClass uyguladığı için burada çalışır Serializable.


daha fazla açıklayabilir veya ayrıntılandırabilir misiniz
Amitsharma

HomeworkData homeworkData = homeWorksList.get (konum); Niyet niyeti = yeni Niyet (c, HomeWorkActivitydetail.class); Paket b = yeni Paket (); b.putSerializable ("CompleteData", homeworkData); intent.putExtras (b) c.startActivity (niyet); nesne eklemek bir anda bana nesne öğeleri eklemek için bazı hata verir bu ile tam bir nesne geçemez
miyim

Veri

12

Samuh'un tanımladığı yöntemi kullanmayı seçerseniz, yalnızca ilkel değerlerin gönderilebileceğini unutmayın. Yani, parsable değerler. Dolayısıyla, nesneniz karmaşık nesneler içeriyorsa, bunlar takip edilmez. Örneğin, Bitmap, HashMap vb. Gibi değişkenler ... Bunlar niyetten geçmek zor.

Genelde Davanıza olurdu String, int, boolean vb gibi ekstra olarak sadece ilkel veri türlerini göndermenizi tavsiye ediyorum: String fname, String lname, int age, ve String address.

Benim düşüncem: Daha karmaşık nesneler daha iyi bir ContentProvider , SDCard , vb uygulanarak paylaşılır . Statik bir değişken kullanmak da mümkündür , ancak bu hızla hataya eğilimli koda yol açabilir ...

Ama yine de, bu sadece öznel görüşüm.


8

Bir etkinlikten başka bir etkinliğe veri göndermek için parcelable kullanıyorum. İşte benim projemde iyi çalışan kodum.

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

Bu şekilde kullanın:

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

ActivityB'de veri almak için şu şekilde kullanın:

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

7

Bu sınıfı kullanmayı deneyebilirsiniz. Sınırlama, bir işlemin dışında kullanılamamasıdır.

Bir etkinlik:

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

Diğer faaliyetler:

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

6

Bu etkinlikten başka bir etkinlik başlatın ve parametreleri Bundle Object ile geçirin

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

Başka bir etkinliğe ilişkin verileri alma (YourActivity)

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

Bu basit veri türü için uygundur. Ama u aktivite arasında karmaşık veri geçmek istiyorsanız. Önce seri hale getirmeniz gerekiyor.

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

TipToken <> kullanımdan kaldırıldı. Alternatif nedir?
Ragavendra M

6

Bu soru, başka bir Yığın Taşması sorusunda da tartışılmaktadır. Lütfen Serializable kullanarak verileri aktarma konusunda bir çözüme göz atın . Ana nokta, Bundlegerekli verileri içinde saklayan nesneyi kullanmakla ilgilidir Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

Değerleri ayıklamak için:

 Bundle bundle = new Bundle();

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

Avantajı Serializablesadeliği. Ancak, Android için özel olarak tasarlandığından ve daha verimli Parcelableolduğundan Parcelable, aktarılacak birçok veriye ihtiyacınız varsa yöntemi kullanmayı düşünmelisiniz Serializable. Aşağıdakileri kullanarak Parcelablesınıf oluşturabilirsiniz:

  1. çevrimiçi bir araç - parcelabler
  2. Studio için bir eklenti - Android Parcelable code generator

5

Fasulye sınıfı gibi bir sınıfı girip Serializablearayüzü uygulayın. Sonra bunu intentyöntemden geçirebiliriz , örneğin:

intent.putExtra("class", BeanClass);

Sonra diğer etkinlikten alın, örneğin:

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

5

Özel Sınıfınızda böyle iki yöntem oluşturun

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

Şimdi göndericinizde Aktivite bunu beğendi

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

Ve alıcınızın Etkinliğinde

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

3

Evet, statik bir nesne kullanmak bunu özel serileştirilemeyen nesnelerle yapmanın en kolay yoludur.


Evet, sanırım aslında sana katılıyorum. staticAktarmak putExtra()istediğiniz her mülkü çağırmaya devam etmek pratik değilse, bu nesneleri yapmak daha iyi bir çözümdür . Örneğin, şu anda, ArrayListnesneleri içeren bir iletmek istiyorum . Bunun staticyerine ArrayList'imi de yapabilirim .
Matthew Quiros

3

Android Etkinlik nesneleri yok edilebilir ve yeniden oluşturulabilir. Yani, onlara bakmak için başka bir yaklaşım kullanmanız gerekecek - veya oluşturdukları herhangi bir nesne !!! - yukarı. Yani, statik sınıf başvurusu olarak geçebilirsiniz, ancak nesne tutamacı (Java, SmallTalk gibi bu "başvuruları" çağırır; ancak C veya derleme anlamında başvurular değildir) bir "özellik" nedeniyle daha sonra geçersiz olacaktır. Android OE herhangi bir Etkinlik daha sonra imha edilebilir ve sulandırılabilir olduğunu.

Orijinal soru "Nesne Android'de bir etkinlikten diğerine nasıl geçirilir" diye sordu ve kimse buna cevap vermedi. Herhalde, serileştirilebilir (Serializable, Parcelable, JSON'a / JSON'dan) ve nesne verilerinin bir kopyasını iletebilirsiniz ve aynı verilere sahip yeni bir nesne oluşturulabilir; ancak aynı referanslara / tanıtıcılara sahip DEĞİLDİR. Ayrıca, diğer birçok referansı statik bir mağazada saklayabilirsiniz. Ve Android etkinliğinizi yok etmeye karar vermedikçe bu işe yarayacaktır.

Bu nedenle, orijinal soruyu gerçekten çözmek için statik bir aramaya ihtiyacınız olacak ve her nesne yeniden oluşturulduğunda / yeniden oluşturulduğunda referansını güncelleyecektir. Örneğin, onCreate çağrılırsa her Android Etkinliği kendini serbest bırakır. Ayrıca bazı kişilerin bir Etkinliği ada göre aramak için görev listesini nasıl kullandığını da görebilirsiniz. (sistem, yerden tasarruf etmek için etkinliğin bu örneğini geçici olarak yok eder ... getRunningTasks, görev listesi etkin bir şekilde her bir Etkinliğin en son nesne örneğinin özel bir listesidir).

Referans için:

Durduruldu: "Etkinlik başka bir etkinlik tarafından tamamen gizlendi (etkinlik artık" arka planda "). Durdurulmuş bir etkinlik de hala canlı ( Activity nesnesi bellekte tutulur , tüm durum ve üye bilgilerini korur, ancak Ancak, artık kullanıcı tarafından görülemez ve başka bir yerde bellek gerektiğinde sistem tarafından öldürülebilir. "

onDestroy "sistem yerden tasarruf etmek için etkinliğin bu örneğini geçici olarak yok ediyor ."

Bu nedenle, Message Bus uygulanabilir bir çözümdür. Temelde "punts". Nesnelere referans vermeye çalışmak yerine; sonra SequentialCode yerine MessagePassing kullanmak için tasarımınızı yeniden mimar. Hata ayıklamak katlanarak daha zor; ancak bu tür bir İşletim Ortamı anlamalarını göz ardı etmenizi sağlar. Etkili olarak, her nesne yöntemi erişimi ters çevrilir, böylece arayan bir Mesaj gönderir ve nesnenin kendisi bu mesaj için bir işleyici tanımlar. Çok daha fazla kod ancak Android OE kısıtlamaları ile sağlam hale getirebilir.

İstediğiniz tek şey en üst Etkinlikse (her yerde "Bağlam" gerektiğinden Android uygulamalarındaki tipik bir şey) ise, onResume çağrıldığında her bir Etkinliğin kendisini statik küresel alanda "üst" olarak listelemesini sağlayabilirsiniz. Daha sonra AlertDialog'unuz veya bir bağlam gerektiren her şey onu oradan alabilir. Ayrıca, bir küresel kullanmak için biraz yucky ama bir Bağlam her yerde yukarı ve aşağı geçiş basitleştirebilir ve tabii ki, bir MessageBus kullandığınızda o zaman IT zaten küreseldir.


Otto, sadece eski bir Java uygulamasında harici olarak çalıştırabiliyor. Yani, Android ile uğraşmak zorunda kalmadan geliştirici ve test için iyi. Otto büyük öğrenme eğrisine sahiptir ve çözdüğü şeylerin çoğu zaten Android yollarında (yerel yayın vb.) Veya normal uygulama geliştirme yaklaşımlarında (Otto'nun küresel aramalarından çok daha basit bir küresel arama yazabilirsiniz, normal yaklaşımlar çoktur) kodlama yoluyla vektörleme / F3 ve hata ayıklama yoluyla adım atma için daha uygun).
TimJowers2

2
  1. Statikin kötü olduğunu biliyorum, ama görünüşe göre burada kullanmak zorundayız. Parseller / seriazable'lar ile ilgili sorun, iki aktivitenin aynı nesnenin yinelenen örneklerine sahip olması = bellek ve CPU kaybıdır.

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

Çağrı etkinliği

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

Aranan etkinlik ( sistem etkinlikleri yok edip yeniden oluşturduğunda onCreate () ve onResume () öğelerinin birden çok kez çağrılabileceğini unutmayın )

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Başka bir yol da, o sınıfa geçmek istediğiniz sınıfın statik bir alanını bildirmektir. Yalnızca bu amaca hizmet edecektir. Uygulama paketinizin sistem tarafından bellekten kaldırıldığı ve daha sonra yeniden yüklendiği için onCreate'de boş olabileceğini unutmayın.

  2. Etkinlik yaşam döngüsünü hala ele almanız gerektiğini göz önünde bulundurarak, tüm verileri doğrudan paylaşılan tercihlere, karmaşık veri yapılarıyla olduğu gibi acı verici olarak yazmak isteyebilirsiniz.


1

Neredeyse hepsi doğru ama olanlar için cevaplar Üstü kim Android güçlü sınıfa sahip bu cevapları anlamamıza gelmez Niyet biz ContetnResolver sınıfını hiçbir Niyet kullanmak size aktivite ancak Android (broadcasr alıcı, içerik servises sağlamak başka bileşenler sadece arasında veri paylaşımı bunun yardımıyla ). Faaliyetinizde niyet oluşturuyorsunuz

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

Alıştırma faaliyetinizde

public class SomeActivity extends AppCompactActivity {

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

}

Etkinlikler arasında paylaşımda bulunmak için nesnenize Parceable veya Serializable arabirimi uygulamanız gerekir. Serializable arabirimi yerine Parcealbe'yi uygulamak zordur , bu yüzden android özellikle bunun için eklentiye sahiptir.


0

Bunun neden diğer aktivitenin bir yöntemini çağırmak kadar basit olamayacağını merak etmiştim. Son zamanlarda neredeyse bu kadar basit hale getiren bir yardımcı program kütüphanesi yazdım. Buradan kontrol edebilirsiniz ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).

GNLauncher , başka bir Etkinlikten bir Etkinliğe vb. Bir Etkinliğe nesne / veri göndermeyi, Etkinlik'te gerekli verileri parametre olarak içeren bir işlevi çağırmak kadar kolaylaştırır. Tip güvenliğini sağlar ve dizgi yapmak, dizgi tuşlarını kullanarak amaca bağlanmak ve diğer uçta bunları geri almak zorunda kalmanın tüm zorluklarını kaldırır.

kullanım

Başlatmak için Etkinlik'te çağırmak istediğiniz yöntemlerin bulunduğu bir arabirim tanımlayın.

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

Başlatmak için Aktivite yukarıdaki arayüzü uygulayın. Ayrıca etkinlik hazır olduğunda GNLauncher'ı bilgilendirin.

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

Diğer Etkinlikte, yukarıdaki Etkinliğe bir proxy alın ve istenen parametrelerle herhangi bir yöntemi çağırın.

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

İlk aktivite başlatılacak ve yöntem gerekli parametrelerle çağrılacaktır.

Ön şartlar

Bağımlılıkların nasıl ekleneceği hakkında bilgi için lütfen https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites adresine bakın .


0

Nesneyi bir etkinlikten başka bir etkinliğe geçirme.

(1) kaynak etkinliği

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

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

(2) hedef etkinliği

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

0

Nesneyi aktarmak için Pacelable veya Serializable ile ayarladım, ancak nesneye (model) başka değişkenler eklediğimde, hepsini kaydetmeliyim. Bu çok rahatsız edici.

Nesneleri etkinlikler veya parçalar arasında aktarmak çok kolaydır.

Android DataCache


0

Nesneyi bir aktiviteden başka bir aktiviteye aktarabiliriz:

SupplierDetails poSuppliersDetails = new SupplierDetails();

İçeride poSuppliersDetailsbazı değerlerimiz var. Şimdi bu nesneyi hedef etkinliğe gönderiyorum:

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

Bu ACtivityTwo nasıl elde edilir:

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

0

Bir etkinliği diğerine aktarın:

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

Değerleri alın:

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

-1

Herkese merhaba, birçok iyi seçenek görüyorum ama neden Binding'un kullanılmadığını merak ediyordum?

Bir nesneye referans vermek, nesneleri serileştirmek ve imha etmekten daha etkili görünüyor, ancak sahnelerin arkasında olup olmadığını görmek için derin bir dalış yapmadım.

Bir cilt oluşturmak yeterince basit ...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

Ve kullanmak için parcelable oluşturmak kötü eter değildir.

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

    };
}

Bu mantık gerçekten harika çünkü aslında aktiviteden aktiviteye bir referans geçiyorsunuz.

Boş olup olmadığını ve Binder instanceof MyBinder olup olmadığını kontrol etmenizi tavsiye ederim!

ve bunu uygulamak için ...

Gönder

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

intent.putExtra("MyParcelable", myParcelable);

Geri almak

myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();

Heck birisi deli olsun ve bu enayi gerçek bir jenerik yapabilir.

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.