Bagaimana cara mengirim objek dari satu Aktivitas Android ke yang lain menggunakan Intents?

849

Bagaimana saya bisa meneruskan objek tipe kustom dari satu Kegiatan ke yang lain menggunakan putExtra()metode kelas Intent ?

UMAR
sumber
@UMMA - Anda tidak perlu terus menandai pertanyaan Anda sebagai "Wiki Komunitas". Lihat di sini: meta.stackexchange.com/questions/11740/…
Dave Webb
1
@ Parsesh: tautan yang Anda berikan rusak. bisakah Anda memberikan alternatif?
antiplex
Lihatlah jawaban ini. stackoverflow.com/questions/8857546/…
Heitor Colangelo
saya menemukan metode stackoverflow.com/a/37774966/6456129
Yessy

Jawaban:

751

Jika Anda hanya melewati benda di sekitar maka Parcelable dirancang untuk ini. Dibutuhkan sedikit lebih banyak upaya untuk digunakan daripada menggunakan serialisasi asli Java, tetapi cara ini lebih cepat (dan maksud saya, JAUH lebih cepat).

Dari dokumen, contoh sederhana untuk bagaimana menerapkan adalah:

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

Perhatikan bahwa dalam hal Anda memiliki lebih dari satu bidang untuk mengambil dari Parcel yang diberikan, Anda harus melakukan ini dalam urutan yang sama dengan yang Anda masukkan (yaitu, dalam pendekatan FIFO).

Setelah objek Anda diimplementasikan Parcelable, tinggal memasukkannya ke dalam Intents dengan putExtra () :

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

Kemudian Anda dapat menariknya kembali dengan getParcelableExtra () :

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

Jika Kelas Objek Anda mengimplementasikan Parcelable dan Serializable maka pastikan Anda melakukan cast ke salah satu dari berikut ini:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
Jeremy Logan
sumber
14
Bagaimana ini diterapkan di mana mData adalah objek (misalnya JSONObject) dan bukan int?
Peter Ajtai
301
Mengapa tidak bisa melewatkan objek tanpa semua ini? Kami ingin meneruskan objek yang sudah ada dalam memori.
ceklock
110
@tecnotron aplikasinya karena dalam proses yang berbeda, dan memiliki ruang alamat memori yang terpisah, Anda tidak bisa hanya mengirim pointer (referensi) ke blok memori dalam proses Anda dan berharap itu akan tersedia dalam proses lain.
marcinj
12
Apa yang harus saya lakukan jika saya tidak dapat membuat kelas objek serializible atau Parceable?
Amel Jose
11
@ceklock alasan di balik ini adalah sebagai berikut: Ketika aktivitas berjalan di belakang dan kemudian dibunuh dari memori, dan kemudian ketika pengguna membukanya dari menu baru-baru ini, ia harus membuat Kegiatan di mana ia tinggalkan. Itu harus UI yang sama. Objek tidak ada dalam memori dalam kasus ini. Tetapi tujuannya adalah.
tasomaniac
194

Anda harus membuat cerita bersambung objek menjadi semacam representasi string. Salah satu representasi string yang mungkin adalah JSON, dan salah satu cara termudah untuk membuat serial ke / dari JSON di android, jika Anda bertanya kepada saya, adalah melalui Google GSON .

Dalam hal ini Anda hanya memasukkan nilai string kembali (new Gson()).toJson(myObject);dan mengambil nilai string dan gunakanfromJson untuk mengubahnya kembali ke objek Anda.

Namun, jika objek Anda tidak terlalu kompleks, mungkin tidak sepadan dengan overhead, dan Anda dapat mempertimbangkan untuk melewatkan nilai-nilai terpisah dari objek tersebut.

David Hedlund
sumber
19
Saya menduga karena jawaban fiXedd memecahkan masalah yang sama tanpa menggunakan perpustakaan eksternal, dengan cara yang jauh lebih disukai, bahwa tidak ada yang pernah memiliki alasan untuk pergi dengan solusi yang saya berikan (tidak menyadari, pada saat itu, dari solusi brilian fiXedd)
David Hedlund
5
Saya pikir itu benar. Lebih jauh, JSON adalah protokol yang lebih sesuai untuk klien / server dan bukan thread-to-thread.
mobibob
16
Belum tentu ide yang buruk, esp. karena Gson jauh lebih mudah digunakan daripada mengimplementasikan parcelable untuk semua objek yang ingin Anda kirim.
uvesten
7
karena saya menggunakan gson di aplikasi saya, ini adalah cara yang sangat mudah dan menyenangkan!
Lars
16
Jawaban yang bagus, meskipun solusi lengkapnya adalah String s = (new Gson().toJson(client));dan kemudianCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk
155

Anda dapat mengirim objek serializable melalui niat

// 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 {
} 
Sridhar
sumber
2
Anda dapat mengirim objek Parcelable melalui niat juga.
tony gil
6
"Serializable memang lambat di Android. Borderline sebenarnya tidak berguna dalam banyak kasus." lihat stackoverflow.com/questions/5550670/…
Seraphim
bagaimana jika aktivitas sudah berjalan, apakah perlu melakukan startActivity (i); ? Maksud saya, dapatkah saya membuat aktivitas A menyebut aktivitas B , dan yang mengembalikan data ke aktivitas A ? apakah saya bingung
Francisco Corrales Morales
3
@ Kinerja Seraphim penting jika Anda membuat serial banyak objek, tetapi pengguna tidak akan melihat jika membuat serialisasi satu objek membutuhkan 1 ms atau 10 ms. Jika niat tambahan sudah ada Serializabletetapi tidak Parcelable, jarang ada kerumitan untuk membuatnya Parcelable.
Kevin Krumwiede
67

Untuk situasi di mana Anda tahu Anda akan melewatkan data dalam suatu aplikasi, gunakan "global" (seperti Kelas statis)

Inilah yang dikatakan Dianne Hackborn (hackbod - seorang insinyur perangkat lunak Google Android):

Untuk situasi di mana Anda tahu aktivitas berjalan dalam proses yang sama, Anda bisa berbagi data melalui global. Sebagai contoh, Anda bisa memiliki global HashMap<String, WeakReference<MyInterpreterState>> dan ketika Anda membuat MyInterpreterState baru datang dengan nama unik untuk itu dan memasukkannya ke dalam peta hash; untuk mengirim keadaan itu ke aktivitas lain, cukup masukkan nama unik ke dalam peta hash dan ketika aktivitas kedua dimulai, ia dapat mengambil MyInterpreterState dari peta hash dengan nama yang diterimanya.

Peter Ajtai
sumber
25
ya saya merasa aneh bahwa kita diberi Intent ini untuk digunakan, dan kemudian seorang insinyur top memberitahu kita untuk hanya menggunakan global untuk data kita. Tapi itu ada langsung dari mulut kuda.
Richard Le Mesurier
1
Bukankah refrence yang lemah di sini menjadi korban pengumpulan sampah?
uLYsseus
1
@uLYsseus berpikir itulah idenya, setelah Anda selesai dengan mereka dalam kegiatan ... jadi ketika kegiatan yang relevan dihancurkan, itu akan memungkinkannya untuk gc
Peter Ajtai
1
@RichardLeMesurier Saya memikirkan hal yang sama, tetapi kemudian saya melihat ke pos Google Groups yang dirujuk di atas dari Dianne Hackborn, dan dia menyebutkan bahwa satu-satunya masalah dengan global adalah ketika menggunakan niat implisit (yang dapat meluncurkan aktivitas di luar paket Anda) ). Ini masuk akal, seperti yang disebutkan Dianne, karena kegiatan-kegiatan itu kemungkinan besar tidak memiliki pengetahuan tentang jenis-jenis kebiasaan yang Anda berikan kepada mereka. Begitu saya membacanya, itu menjadi lebih jelas bagi saya mengapa global mungkin bukan rute yang buruk dalam situasi seperti itu, dan saya pikir saya akan berbagi kalau-kalau ada yang ingin tahu juga
BMB
maksudnya terlalu direkayasa ke titik di mana niat dapat diteruskan ke komputer yang berbeda. yang jelas bukan cara yang baik untuk melakukan apa pun ketika Anda sebenarnya hanya memiliki satu proses yang Anda lakukan. Alasan mengapa itu tidak baik: penggunaan memori, penggunaan cpu, penggunaan baterai. yang terakhir terutama membuat pilihan desain dengan niat yang cukup membingungkan. ada orang yang bersikeras bahwa mereka ide yang baik, biasanya karena "google berkata demikian".
Lassi Kinnunen
49

Kelas Anda harus mengimplementasikan Serializable atau Parcelable.

public class MY_CLASS implements Serializable

Setelah selesai, Anda dapat mengirim objek di putExtra

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Untuk mendapatkan ekstra, Anda hanya perlu melakukannya

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

Jika kelas Anda mengimplementasikan penggunaan Parcelable selanjutnya

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

Saya harap ini membantu: D

Pedro Romão
sumber
6
Kelas Anda harus diterapkan Serializablesalah. Kelas dapat diimplementasikan Parcelablemisalnya.
Marc Plano-Lesay
apa perbedaan antara Parcelable dan Serializable @Kernald? dalam hal waktu pemrosesan, apakah lebih lambat / bukan praktik terbaik atau semacamnya?
gumuruh
Sementara Serializableantarmuka Java standar, Parcelableadalah khusus Android. Dalam hal kinerja, Parcelable lebih efisien: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay
35

Jawaban singkat untuk kebutuhan cepat

1. Terapkan Kelas Anda ke Serializable.

Jika Anda memiliki Kelas Batin jangan lupa untuk mengimplementasikannya ke Serializable juga !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Masukkan objek Anda ke Intent

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

3. Dan terima objek Anda di Kelas Aktivitas lainnya

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");
Sam
sumber
lihat tautan ini, stackoverflow.com/questions/2139134/…
RejoylinLokeshwaran
Anda dapat mencapai hal yang sama dengan mengimplementasikan antarmuka Parcelable. Antarmuka parcelable membutuhkan waktu lebih lama untuk diimplementasikan dibandingkan dengan Serializable karena ukuran kode. Tetapi kinerjanya lebih cepat daripada Serializable dan menggunakan lebih sedikit sumber daya.
Kwnstantinos Nikoloutsos
27

jika kelas objek Anda mengimplementasikan Serializable, Anda tidak perlu melakukan hal lain, Anda bisa melewatkan objek serial.
itu yang saya gunakan.

Vlad
sumber
24

mengimplementasikan serializable di kelas Anda

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

Kemudian Anda bisa melewatkan objek ini dengan niat

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

int aktivitas kedua Anda bisa mendapatkan data seperti ini

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

Tetapi ketika data menjadi besar, metode ini akan lambat.

Ishan Fernando
sumber
16

Anda dapat menggunakan BUNDLE android untuk melakukan ini.

Buat Bundel dari kelas Anda seperti:

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

    return b;
}

Kemudian sampaikan bundel ini dengan INTENT. Sekarang Anda dapat membuat ulang objek kelas Anda dengan mengirimkan bundel like

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

Nyatakan ini di kelas Kustom Anda dan gunakan.

om252345
sumber
1
Lebih disukai untuk mengarahkan implementasi Parcelable, IMHO. Bundle mengimplementasikan Parcelable dengan sendirinya sehingga Anda masih memiliki perolehan kinerja sambil menghindari semua kesulitan mengimplementasikannya sendiri. Sebagai gantinya, Anda dapat menggunakan pasangan nilai kunci untuk menyimpan dan mengambil data yang jauh lebih kuat daripada mengandalkan pesanan belaka.
Risadinha
Parcelable tampaknya rumit bagi saya, dalam jawaban saya di atas saya menggunakan metode toBundle dari kelas pada objek itu sehingga objek dikonversi ke bundel dan kemudian kita dapat menggunakan konstruktor untuk mengkonversi bundel ke objek kelas.
om252345
Solusi ini hanya dapat digunakan jika Anda melewati satu objek melalui niat.
TheIT
Seperti json tetapi json ringan menurut saya.
David
Apakah objek ketika saya mengambilnya akan menjadi objek yang sama atau salinan?
Markus
16

Ada beberapa cara di mana Anda dapat mengakses variabel atau objek di kelas atau Kegiatan lainnya.

A. Basis Data

B. preferensi bersama.

C. Serialisasi objek.

D. Kelas yang bisa menampung data umum bisa dinamai Utilitas Umum itu tergantung Anda.

E. Melewati data melalui Intents dan Interface Parcelable.

Itu tergantung pada kebutuhan proyek Anda.

A. Basis Data

SQLite adalah Basis Data Sumber Terbuka yang disematkan ke Android. SQLite mendukung fitur basis data relasional standar seperti sintaks SQL, transaksi, dan pernyataan yang disiapkan.

Tutorial - http://www.vogella.com/articles/AndroidSQLite/article.html

B. Preferensi Bersama

Misalkan Anda ingin menyimpan nama pengguna. Jadi sekarang akan ada dua hal Nama Pengguna Utama , Nilai Nilai.

Cara menyimpan

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

Menggunakan putString (), putBoolean (), putInt (), putFloat (), putLong () Anda dapat menyimpan dtatype yang Anda inginkan.

Cara mengambil

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

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

C. Serialisasi objek

Serialisasi objek digunakan jika kami ingin menyimpan status objek untuk mengirimkannya melalui jaringan atau Anda dapat menggunakannya untuk tujuan Anda juga.

Gunakan kacang java dan simpan di dalamnya sebagai salah satu bidangnya dan gunakan getter dan setter untuk itu

JavaBeans adalah kelas Java yang memiliki properti. Pikirkan properti sebagai variabel instance pribadi. Karena bersifat pribadi, satu-satunya cara mereka dapat diakses dari luar kelas mereka adalah melalui metode di kelas. Metode yang mengubah nilai properti disebut metode setter, dan metode yang mengambil nilai properti disebut metode pengambil.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

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


}

Tetapkan variabel dalam metode email Anda dengan menggunakan

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

Kemudian gunakan Serialisasi objek untuk membuat serialisasi objek ini dan di kelas Anda yang lain deserialize objek ini.

Dalam serialisasi, suatu objek dapat direpresentasikan sebagai urutan byte yang mencakup data objek serta informasi tentang tipe objek dan tipe data yang disimpan dalam objek.

Setelah objek serial telah ditulis ke dalam file, itu dapat dibaca dari file dan deserialized yaitu, informasi jenis dan byte yang mewakili objek dan datanya dapat digunakan untuk membuat ulang objek dalam memori.

Jika Anda ingin tutorial untuk ini merujuk tautan ini

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

Dapatkan variabel di kelas lain

D. CommonUtilities

Anda dapat membuat kelas sendiri yang dapat berisi data umum yang sering Anda butuhkan dalam proyek Anda.

Sampel

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Mengirim Data melalui Intents

Silakan merujuk ke tutorial ini untuk opsi pengiriman data ini.

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

Nikhil Agrawal
sumber
Tutorial bagus yang Anda sebutkan dalam (E) tentang meneruskan data melalui Intents.
remrick
15

Terima kasih atas bantuan parcelable tetapi saya menemukan satu lagi solusi opsional

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

Di Aktivitas Satu

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

Dapatkan Data Dalam Aktivitas 2

 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());
        }
pengguna1140237
sumber
1
jawaban yang bagus, tetapi tingkatkan Standar Pengodean Anda ... +1 meskipun untuk membawa Serializable dalam kompetisi namun Parcellables jauh lebih cepat ...
Amit
13

Saya menggunakan Gson dengan api yang begitu kuat dan sederhana untuk mengirim objek di antara aktivitas,

Contoh

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

2 fungsi yang Anda tambahkan ke objek yang ingin Anda kirim

Pemakaian

Kirim Obyek Dari A ke B

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

Terima B

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

Saya menggunakannya hampir di setiap proyek yang saya lakukan dan saya tidak memiliki masalah kinerja.

MBH
sumber
Terima kasih, ini menyelamatkan saya dari kerumitan yang berlebih.
Hristo Stoyanov
10

Saya berjuang dengan masalah yang sama. Saya menyelesaikannya dengan menggunakan kelas statis, menyimpan data yang saya inginkan di HashMap. Di atas saya menggunakan ekstensi dari kelas Kegiatan standar di mana saya telah menimpa metode onCreate onDestroy untuk melakukan transportasi data dan pembersihan data tersembunyi. Beberapa pengaturan konyol harus diubah misalnya penanganan orientasi.

Anotasi: Tidak menyediakan objek umum untuk diteruskan ke Aktivitas lain adalah rasa sakit di pantat. Ini seperti menembak diri sendiri di lutut dan berharap untuk memenangkan 100 meter. "Parcable" bukan pengganti yang memadai. Itu membuat saya tertawa ... Saya tidak ingin mengimplementasikan antarmuka ini ke API bebas teknologi saya, karena semakin sedikit saya ingin memperkenalkan Layer baru ... Bagaimana mungkin, bahwa kita berada dalam pemrograman seluler yang sangat jauh dari paradigma modern ...

oopexpert
sumber
9

Dalam Aktivitas pertama Anda:

intent.putExtra("myTag", yourObject);

Dan yang kedua:

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

Jangan lupa untuk membuat objek khusus Anda Serializable:

public class myCustomObject implements Serializable {
...
}
Rudi
sumber
Parcelable lebih baik daripada Serializable! Hindari menggunakan Serializable dalam kode Android Anda!
Filipe Brito
7

Cara lain untuk melakukan ini adalah dengan menggunakan Applicationobjek (android.app.Application). Anda mendefinisikan ini dalam AndroidManifest.xmlfile Anda sebagai:

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

Anda kemudian dapat memanggil ini dari aktivitas apa pun dan menyimpan objek ke Applicationkelas.

Dalam FirstActivity:

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

Di SecondActivity, lakukan:

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

Ini berguna jika Anda memiliki objek yang memiliki cakupan tingkat aplikasi, yaitu objek tersebut harus digunakan di seluruh aplikasi. ItuParcelable Metode ini masih lebih baik jika Anda ingin kontrol eksplisit atas lingkup objek atau jika ruang lingkup terbatas.

Ini menghindari penggunaan Intentssama sekali. Saya tidak tahu apakah itu cocok untuk Anda. Cara lain yang saya gunakan adalah memiliki intpengidentifikasi objek yang dikirim melalui maksud dan mengambil objek yang saya miliki di Maps di Applicationobjek.

Saad Farooq
sumber
1
Ini bukan cara yang tepat untuk melakukan sesuatu karena objek mungkin variabel, milik Anda dapat bekerja jika Anda berbicara tentang objek statis di sepanjang siklus aplikasi, tetapi beberapa kali kita membutuhkan objek pasif yang dapat dihasilkan menggunakan layanan web atau lebih stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri
Saya telah berhasil menggunakannya dengan objek yang dihasilkan dari layanan web dengan memiliki cakupan aplikasi Maptempat objek disimpan dan diambil dengan menggunakan pengenal. Satu-satunya masalah nyata dengan pendekatan ini adalah bahwa Android membersihkan memori setelah beberapa saat sehingga Anda harus memeriksa nol pada onResume Anda (saya pikir Objects yang lewat dalam maksud tetap ada tetapi tidak yakin). Selain itu saya tidak melihat ini secara signifikan lebih rendah.
Saad Farooq
Ini jawaban terbaik. Ini menunjukkan bagaimana berbagai kegiatan dapat mereferensikan model data yang sama. Butuh waktu lama untuk menemukan ini!
Markus
6

di model kelas Anda (Obyek) mengimplementasikan Serializable, misalnya:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

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


}

dan Aktivitas pertama Anda

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

dan Aktivitas kedua Anda (Aktivitas Baru)

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

semoga berhasil!!

David Hackro
sumber
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];
        }
    };

}

Melewati data:

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

Mengambil data:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
Adnan Abdollah Zaki
sumber
5

solusi termudah yang saya temukan adalah .. untuk membuat kelas dengan anggota data statis dengan setter setter.

atur dari satu aktivitas dan dapatkan dari aktivitas lain objek itu.

aktivitas A

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

aktivitas b

mytestclass obj= mytestclass.staticfunctionGet();
UMAR
sumber
1
atau membuat kelas serial untuk membuat aktivitas lain apa pun yang Anda inginkan.
UMAR
9
Ingatlah untuk tidak menaruh benda besar yang gemuk. Masa pakai objek itu akan sama dengan masa pakai aplikasi. Dan tidak pernah menyimpan tampilan. Metode ini juga menjamin kebocoran memori.
Reno
1
Jawaban ini bermanfaat tetapi bukan solusi yang lebih baik dalam hal memori dan optimalisasi sumber daya
Atul Bhardwaj
1
Ini melanggar prinsip-prinsip OOP dengan memperkenalkan variabel global. Anda tidak pernah tahu, di negara mana mereka berada, apakah sudah disetel atau tidak, mereka digunakan oleh banyak utas dan Anda harus berurusan dengan kompleksitas ini. Ini biasanya merupakan kebocoran memori yang baik, karena Anda bahkan tidak tahu, kapan harus membebaskan variabel-variabel ini. Bukan untuk mengatakan bahwa itu memperkenalkan sambungan langsung keras antara berbagai modul aplikasi.
afrish
2
WTF? Dua jawaban lainnya jauh lebih unggul.
IcyFlame
4

Anda dapat menggunakan metode putExtra (Serializable ..) dan getSerializableExtra () untuk meneruskan dan mengambil objek dari tipe kelas Anda; Anda harus menandai kelas Anda Serializable dan pastikan bahwa semua variabel anggota Anda serializable juga ...

batal
sumber
4

Buat Aplikasi Android

File >> Baru >> Aplikasi Android

Masukkan Nama proyek: android-pass-objek-ke-aktivitas

Pakcage: com.hmkcode.android

Simpan pilihan defualt lainnya, lanjutkan Berikutnya hingga Anda mencapai Selesai

Sebelum mulai membuat Aplikasi, kita perlu membuat POJO kelas "Person" yang akan kita gunakan untuk mengirim objek dari satu aktivitas ke aktivitas lainnya. Perhatikan bahwa kelas mengimplementasikan antarmuka Serializable.

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

Dua Tata Letak untuk Dua Kegiatan

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>

Dua Kelas Kegiatan

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

}
}
MFP
sumber
4

Menggunakan pustaka Gson google, Anda dapat meneruskan objek ke aktivitas lain. Sebenarnya kami akan mengonversi objek dalam bentuk string json dan setelah meneruskan ke aktivitas lain, kami akan kembali mengonversi kembali ke objek seperti ini

Pertimbangkan kelas kacang seperti ini

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

Kita harus melewati objek kelas Contoh

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

Untuk membaca, kita perlu melakukan operasi terbalik di NextActivity

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

Tambahkan ketergantungan ini dalam gradle

compile 'com.google.code.gson:gson:2.6.2'
Jinesh Francis
sumber
3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
Manas Ranjan
sumber
3

Saya tahu ini sudah terlambat tetapi sangat sederhana. Yang harus Anda lakukan adalah membiarkan kelas Anda mengimplementasikan Serializable seperti

public class MyClass implements Serializable{

}

maka Anda dapat beralih ke niat seperti

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

Untuk mendapatkannya, Anda menelepon

MyClass objec=(MyClass)intent.getExtra("theString");
suulisin
sumber
2

Jika Anda memiliki kelas singleton (fx Service) yang bertindak sebagai gateway ke lapisan model Anda, itu dapat diselesaikan dengan memiliki variabel di kelas itu dengan getter dan setter untuk itu.

Dalam Kegiatan 1:

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

Dalam Aktivitas 2:

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

Dalam pelayanan:

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

Solusi ini tidak memerlukan serialisasi atau "pengemasan" lain dari objek yang dimaksud. Tapi itu hanya akan bermanfaat jika Anda menggunakan jenis arsitektur ini.

Kitalda
sumber
Apa kerugian dari pendekatan ini? Tampaknya sangat logis dan ramping. Saya selalu membaca Anda tidak harus melakukan itu tetapi saya tidak pernah mendapatkan penjelasan yang baik tentang apa yang bisa salah.
Markus
Karena saya tidak dapat mengedit komentar saya lagi: Bukankah ini satu-satunya solusi yang mungkin untuk mendapatkan referensi ke suatu objek daripada salinan? Saya perlu mengambil obejct yang sama dan bukan salinan!
Markus
Saya pikir ini agak berkecil hati karena kopling tinggi itu mengarah ke. Tapi ya, sejauh yang saya bisa lihat, pendekatan ini adalah yang paling layak jika Anda membutuhkan objek yang sebenarnya. Seperti biasa dalam pemrograman, Anda dapat melakukan apa pun yang Anda inginkan, Anda hanya ingin melakukannya dengan hati-hati. Solusi ini bekerja untuk saya, dan saya lebih suka karena saya tetap menggunakan arsitektur itu.
Kitalda
Sebenarnya saya akhirnya memperluas kelas Aplikasi dan menyimpan model data saya di sana. Dalam Intents, saya hanya menyampaikan ID objek data yang dapat digunakan untuk mengambil objek asli dari kelas Aplikasi. Juga kelas aplikasi yang diperluas memberi tahu semua objek yang menggunakan datamodel jika itu berubah melalui konsep pendengar standar. Saya tahu bahwa ini hanya cocok untuk kasus saya di mana saya perlu berbagi model data atas seluruh aplikasi tetapi untuk kasus itu sempurna dan tidak ada kelas dan bidang statis yang diperlukan juga!
Markus
2

Sejauh ini cara termudah IMHO untuk membagi-bagi benda. Anda cukup menambahkan tag anotasi di atas objek yang ingin Anda buat parcelable.

Contoh dari perpustakaan di bawah ini 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; }
}
Ryan
sumber
2

Pertama implementasikan Parcelable di kelas Anda. Lalu lewati objek seperti ini.

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 string tidak perlu, hanya string yang harus sama di kedua Kegiatan

REFERENSI

Arpit Patel
sumber
2

Mulai aktivitas lain dari parameter lulus aktivitas ini melalui Bundle Object

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

Ambil aktivitas lain (YourActivity)

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

Ini ok untuk tipe data jenis sederhana. Tetapi jika Anda ingin mengirimkan data yang kompleks di antara aktivitas, Anda harus membuat serial terlebih dahulu.

Di sini kita memiliki Model Karyawan

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

    getters...
    setters...
}

Anda dapat menggunakan Gson lib yang disediakan oleh google untuk membuat serial data yang kompleks seperti ini

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);
user1101821
sumber
2

Di Koltin

Tambahkan ekstensi kotlin di build.gradle Anda.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Kemudian buat kelas data Anda seperti ini.

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

Lulus Obyek dengan Intent

val sample = Sample(1,"naveen")

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

Dapatkan objek dengan niat

val sample = intent.getParcelableExtra("id")
Naveen
sumber
Apakah masih eksperimental?
ShadeToD
2

Cara paling mudah dan java untuk melakukan adalah: mengimplementasikan serializable di kelas pojo / model Anda

Disarankan untuk Android untuk tampilan kinerja: buat model parcelable

Ashok Kumar
sumber
1

Yang paling sederhana adalah dengan menggunakan berikut ini di mana item tersebut adalah string:

intent.putextra("selected_item",item)

Untuk menerima:

String name = data.getStringExtra("selected_item");
ankish
sumber
3
untuk string, integer dan lain-lain tetapi saya ingin objek dan menggunakan objek statis hanya mungkin.
UMAR