Cara meneruskan objek dari satu aktivitas ke aktivitas lainnya di Android

779

Saya mencoba bekerja mengirim objek kelas pelanggan saya dari satu Activitydan menampilkannya di yang lain Activity.

Kode untuk kelas pelanggan:

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

Saya ingin mengirim objeknya dari satu Activityke yang lain dan kemudian menampilkan data di sisi lain Activity.

Bagaimana saya bisa mencapainya?

kaibuki
sumber
1
mungkin Anda harus mengubah jawaban yang diterima mengingat pendapat massa.
Rohit Vipin Mathews
Saya biasa mengatur objek ke Pacelable atau Serializable, tetapi setiap kali saya menambahkan variabel lain, saya harus menambahkan semuanya ke fungsi untuk mendapatkan dan ditetapkan untuk Pacelable atau Serializable. jadi saya membuat DataCache untuk mentransfer antara aktivitas dan fragmen. github.com/kimkevin/AndroidDataCache Sangat mudah untuk mentransfer objek.
kimkevin

Jawaban:

886

Salah satu opsi bisa membiarkan kelas kustom Anda mengimplementasikan Serializableantarmuka dan kemudian Anda bisa melewatkan instance objek dalam maksud tambahan menggunakan putExtra(Serializable..)varian Intent#putExtra()metode.

Kodesemu :

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

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

Catatan: Pastikan setiap kelas bersarang dari kelas khusus utama Anda telah mengimplementasikan antarmuka Serializable untuk menghindari pengecualian serialisasi. Sebagai contoh:

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}
Samuh
sumber
126
@OD: Dalam pembelaan saya, saya tidak pernah mengatakan ini adalah pilihan terbaik; OP hanya meminta alternatif dan saya menyarankan satu. Terima kasih.
Samuh
83
Mengapa Serializable bukan opsi yang baik? Ini adalah antarmuka yang terkenal, ada kemungkinan besar bahwa kelas-kelas orang mungkin sudah mengimplementasikannya (ArrayList, misalnya, sudah Serializable). Mengapa Anda harus mengubah objek data Anda untuk menambahkan kode tambahan hanya untuk meneruskannya dari satu kelas ke kelas lain? Itu sepertinya desain yang buruk. Saya bisa membayangkan mungkin ada beberapa dampak kinerja pada tingkat tertentu, tetapi saya akan berpikir bahwa dalam 99% kasus, orang melewati sejumlah kecil data, dan mereka tidak akan peduli. Lebih sederhana dan portabel kadang lebih baik juga.
Nate
16
@Sand: Apakah jawaban ini ( stackoverflow.com/questions/2139134/… ) salah? Dia mengatakan bahwa Parcelable IS dirancang khusus untuk tujuan itu (dan jauh lebih cepat daripada Serializable). Saya bingung.
Slauma
41
Parcelablemungkin bagus untuk kecepatan, tetapi rumit untuk diterapkan. Bagaimana jika Anda memiliki 8 objek yang harus Anda lewati di antara aktivitas, apakah Anda akan membuat masing-masing Parcelable? Akan lebih masuk akal untuk digunakan Serializablesebagai gantinya. Ketika Anda menerapkan ParcelableAnda harus menambahkan banyak kode ke kelas, dan memesan bidang dengan cara yang sangat spesifik; Serializablekamu tidak. Pada akhirnya, saya pikir itu tergantung pada berapa banyak objek yang Anda lewati dan apa yang Anda coba lakukan.
BlackHatSamurai
15
Serializableadalah antarmuka Java standar. Anda cukup menandai kelas Serializable dengan mengimplementasikan antarmuka, dan Java akan secara otomatis membuat cerita bersambung dalam situasi tertentu. Parcelableadalah antarmuka spesifik Android tempat Anda mengimplementasikan sendiri serialisasi itu. Itu diciptakan untuk menjadi jauh lebih efisien daripada Serializable, dan untuk mengatasi beberapa masalah dengan skema serialisasi Java default
Gaurav Arora
311

Laksanakan kelas Anda dengan Serializable. Anggaplah ini kelas entitas Anda:

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

Kami mengirim objek yang dipanggil denedari aktivitas X ke aktivitas Y. Di suatu tempat dalam aktivitas X;

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

Dalam aktivitas Y kita mendapatkan objek.

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

Itu dia.

Mustafa Güven
sumber
1
Itu sangat membantu saya. Terima kasih ... Tetapi ketika menerima objek yang diteruskan, sintaksis seharusnya [Deneme dene = (Deneme) i.getSerializableExtra ("sampleObject"); ] ... Apakah itu ???
JibW
1
@ MustafaGüven Tapi saya bisa classCastException: java.lang.Longmelakukannya. Bisakah Anda jelaskan mengapa?
Shajeel Afzal
Tidak ada hubungan dengan jawaban saya. Ini hal yang sangat berbeda yang Anda dapatkan. Bisakah Anda membagikan kode Anda?
Mustafa Güven
1
Serializable terlalu lambat untuk POJO besar. Menggunakan Bus adalah pola yang jauh lebih baik.
Steven Mark Ford
1
Mengapa saya harus awalan (Serializable)ke objek?
Alston
123
  • Menggunakan variabel statis global bukanlah praktik rekayasa perangkat lunak yang baik .
  • Mengubah bidang objek menjadi tipe data primitif bisa menjadi pekerjaan yang sibuk .
  • Menggunakan serializable tidak apa-apa, tetapi tidak efisien dalam platform Android.
  • Parcelable dirancang khusus untuk Android dan Anda harus menggunakannya. Berikut adalah contoh sederhana: Melewati objek khusus di antara aktivitas Android

Anda dapat menghasilkan kode Parcelable untuk kelas Anda menggunakan situs ini .

SohailAziz
sumber
4
Bagaimana jika objek saya mengandung Arraylist bersarang?
Dr. aNdRO
10
Yah mungkin tapi kita harus benar-benar mengambil `` kinerja '' dengan sebutir garam imo. Jika itu datang pada harga implementasi Parcelablemaka saya lebih suka menjaga kelas POJO saya Android-agnostik dan digunakan Serializable.
VH-NZZ
Saya tidak setuju bahwa Anda harus menggunakan Parcelable. Pola BUS sederhana jauh lebih efisien saat runtime dan menghemat banyak waktu dev.
Steven Mark Ford
15
Menurut tolok ukur ini, bitbucket.org/afrishman/androidserializationtest Serializable jauh lebih cepat daripada Parcelable. Tolong berhenti berbagi omong kosong 5 tahun tentang Parcelable ini.
afrish
7
Bagaimana variabel statis global "bukan praktik rekayasa perangkat lunak yang baik"? Anda dapat membuat sesuatu seperti cache singleton dan / atau kisi data kemudian memberikan ID atau sejenisnya. Ketika Anda meneruskan referensi di Jawa Anda tetap menggunakan variabel statis global dalam arti karena mereka menunjuk ke objek yang sama.
breakline
112

Gunakan gson untuk mengonversi objek Anda ke JSON dan meneruskannya melalui niat. Di Aktivitas baru, konversi JSON ke objek.

Di Anda build.gradle, tambahkan ini ke dependensi Anda

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

Di Aktivitas Anda, konversikan objek ke string-json:

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

Di Aktivitas penerimaan Anda, ubah kembali string json ke objek asli:

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

Bagi Kotlin itu sama saja

Lulus data

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

Terima data

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)
khalid
sumber
3
Ini berlebihan, gson hanyalah sejenis serialisasi string ke json, lebih baik untuk mengimplementasikan Serializable atau Paracable.
James Roeiter
14
Tidak perlu menerapkan serializable di setiap objek dan di setiap proyek (buang-buang waktu) jika Anda dapat menggunakan perpustakaan (gson) yang menangani itu. Dan tentang berlebihan, ada ponsel dual dan quadcore di luar sana, mereka dapat menangani bahkan daftar mengikuti ide jawaban ini.
sagits
4
Saya juga akan merekomendasikan menggunakan gson karena gson juga dapat membuat serial array selain di atas.
nurgasemetey
4
Ini bagus! Dalam kasus saya, saya menggunakan perpustakaan bahwa objek tidak mengimplementasikan serializable atau parcelable. Jadi ini satu-satunya pilihan saya afaik
Chad Bingham
2
Ini adalah opsi "terbaik". Beberapa kelas sangat sederhana, Anda tidak perlu terlalu menyulitkan implementasinya dengan mengimplementasikan serializable
Ojonugwa Jude Ochalifu
98

Saat memanggil suatu aktivitas

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

Di toClass.java menerima aktivitas oleh

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

Harap pastikan bahwa kelas pelanggan menerapkan paket

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();
    }
Iklan
sumber
Adhavan, saya punya pertanyaan. Saat Anda membuat kelas Intent pertama, Anda mengirimkan fromClass.ini sebagai argumen pertama. Apakah ada cara untuk mengambil objek ini di kelas aktivitas penerima?
pemain baru
1
Miliu, fromClass fr = (fromClass) getParent (); apakah ini yang kamu butuhkan?
Iklan
Adhava, saya benar-benar melakukan ini, tetapi fr adalah nol. Ada yang tahu kenapa?
pemain baru
miliu, tolong bagikan jejak pengecualian Anda dengan itu kami bisa memeriksanya.
Iklan
Parcelable memiliki banyak kode pelat ketel yang tidak perlu dan sejujurnya hanya buang-buang waktu. Alih-alih menggunakan Bus. Lihat posting saya di bawah ini.
Steven Mark Ford
89

Dalam pengalaman saya ada tiga solusi utama, masing-masing dengan kekurangan dan kelebihannya:

  1. Menerapkan Parcelable

  2. Menerapkan Serializable

  3. Menggunakan semacam perpustakaan bus acara ringan (misalnya, EventBus Greenrobot atau Otto Square)

Parcelable - standar cepat dan Android, tetapi memiliki banyak kode boilerplate dan membutuhkan string kode keras untuk referensi saat menarik nilai keluar dari maksud (tidak diketik dengan kuat).

Serializable - mendekati nol boilerplate, tetapi merupakan pendekatan paling lambat dan juga membutuhkan string yang dikodekan keras saat menarik nilai keluar dari tujuannya (tidak diketik dengan kuat).

Event Bus - zero boilerplate, pendekatan tercepat, dan tidak memerlukan string hard-coded, tetapi membutuhkan dependensi tambahan (walaupun biasanya ringan, ~ 40 KB)

Saya memposting perbandingan yang sangat rinci di sekitar tiga pendekatan ini, termasuk tolok ukur efisiensi.

Steven Mark Ford
sumber
4
Tautan ke artikel sudah mati. Masih tersedia di webarchive: web.archive.org/web/20160917213123/http://…
OlivierH
Sayang sekali tautannya rusak :(
Mauker
Masalah penggunaan Bus Acara adalah ketika Kegiatan target diciptakan kembali karena rotasi misalnya. Dalam hal ini Kegiatan target tidak memiliki akses ke objek yang lewat karena objek ini dikonsumsi dari bus oleh panggilan sebelumnya.
JuliuszJ
1
Parcelable adalah yang tercepat dan dengan generator ini ( parcelabler.com ), Anda dapat menempelkan kelas Anda dan dapat menghasilkan kode untuk Anda. Sederhana.
ByWaleed
1
@ByWaleed ... Saya sangat setuju, saya selalu menggunakan situs ini, membuat barang tanpa hassels. Namun, saya telah mengalami banyak percobaan yang gagal, ketika saya mencoba menggunakan POJO yang terdiri dari Objek lain. Untuk beberapa alasan itu tidak benar-benar berfungsi.
Aplikasi Yo
42

Saya menemukan metode sederhana & elegan:

  • TIDAK ADA Bingkisan
  • TIDAK Serializable
  • TANPA Bidang Statis
  • Tidak Ada Bus Acara

Metode 1

Kode untuk aktivitas pertama:

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

Kode untuk aktivitas kedua:

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

Anda akan menemukan objSent& objReceivedmemiliki yang sama hashCode, sehingga mereka identik.

Tapi mengapa kita bisa melewatkan objek java dengan cara ini?

Sebenarnya, pengikat android akan membuat referensi JNI global untuk objek java dan melepaskan referensi JNI global ini ketika tidak ada referensi untuk objek java ini. binder akan menyimpan referensi JNI global ini di objek Binder.

* HATI-HATI: metode ini HANYA berfungsi kecuali dua aktivitas berjalan dalam proses yang sama, jika tidak lempar ClassCastException di (ObjectWrapperForBinder) getIntent (). GetExtras (). GetBinder ("object_value") *

class ObjectWrapperForBinder defination

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Metode 2

  • untuk pengirim,
    1. menggunakan metode asli kustom untuk menambahkan objek java Anda ke tabel referensi global JNI (via JNIEnv :: NewGlobalRef)
    2. letakkan integer pengembalian (sebenarnya, JNIEnv :: NewGlobalRef jobject kembali, yang merupakan pointer, kita dapat melemparkannya ke int dengan aman) ke Intent Anda (melalui Intent :: putExtra)
  • untuk penerima
    1. dapatkan integer dari Intent (via Intent :: getInt)
    2. menggunakan metode asli kustom untuk mengembalikan objek java Anda dari tabel referensi global JNI (via JNIEnv :: NewLocalRef)
    3. hapus item dari tabel referensi global JNI (via JNIEnv :: DeleteGlobalRef),

Tetapi Metode 2 memiliki masalah kecil tapi serius, jika penerima gagal mengembalikan objek java (misalnya, beberapa pengecualian terjadi sebelum mengembalikan objek java, atau Kegiatan penerima tidak ada sama sekali), maka objek java akan menjadi anak yatim atau kehabisan memori, Metode 1 tidak memiliki masalah ini, karena pengikat android akan menangani pengecualian ini

Metode 3

Untuk memohon objek java dari jarak jauh, kami akan membuat kontrak data / antarmuka untuk menggambarkan objek java, kami akan menggunakan file aidl

IDataContract.aidl

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

Kode untuk aktivitas pertama

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

Kode untuk aktivitas kedua:

ubah atribut android: process di AndroidManifest.xml menjadi nama proses yang tidak kosong untuk memastikan aktivitas kedua berjalan di proses lain

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

Dengan cara ini, kita dapat melewati antarmuka antara dua aktivitas meskipun mereka berjalan dalam proses yang berbeda, dan memanggil metode antarmuka dari jarak jauh

Metode 4

Metode 3 tampaknya tidak cukup sederhana karena kita harus mengimplementasikan antarmuka Aidl. Jika Anda hanya ingin melakukan tugas sederhana dan nilai metode pengembalian tidak diperlukan, kita dapat menggunakan android.os.Messenger

Kode untuk aktivitas pertama (pengirim):

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

Kode untuk aktivitas kedua (penerima):

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

    }
}

Semua Messenger.send akan mengeksekusi dalam Handler secara tidak sinkron dan berurutan.

Sebenarnya, android.os.Messenger juga merupakan antarmuka Aidl, jika Anda memiliki kode sumber android, Anda dapat menemukan file bernama IMessenger.aidl

package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}
Yessy
sumber
Maaf saya tidak melihat bahwa Anda telah mengikat jawaban Anda juga saya merasa bahwa jawaban Anda juga sangat elegan.
SkidRunner
Wow .... Metode pertama pria ini luar biasa ..... Ketika Anda memiliki benda berukuran sangat besar / lebih besar yang berfungsi dengan baik
karan
Saya pengguna metode satu. Jadi, Anda menghemat waktu saya. Terima kasih;
ShweLiam
Terima kasih banyak untuk metode ObjectWrapperForBinder, sangat membantu!
Vladimir Tolstikov
40

Anda juga bisa menulis data objek ke String dan int sementara, dan meneruskannya ke aktivitas. Tentu saja dengan cara itu, Anda mendapatkan data yang diangkut, tetapi bukan objek itu sendiri.

Tetapi jika Anda hanya ingin menampilkannya, dan tidak menggunakan objek dalam metode lain atau semacamnya, itu sudah cukup. Saya melakukannya dengan cara yang sama untuk hanya menampilkan data dari satu objek dalam aktivitas lain.

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

Anda juga bisa memasukkannya langsung bukan ke temp, tetapi cara ini lebih jelas, menurut saya. Selain itu, Anda dapat mengatur ivar temp ke null sehingga mereka dibersihkan oleh GarbageCollector lebih cepat.

Semoga berhasil!

Di samping catatan: override toString () alih-alih menulis metode cetak Anda sendiri.

Seperti disebutkan dalam komentar di bawah, ini adalah cara Anda mendapatkan data Anda kembali di aktivitas lain:

String fName = getIntent().getExtras().getInt("fname");
MJB
sumber
9
dapatkan kembali data Anda dengan: String fName = getIntent (). getExtras (). getInt ("fname");
Alister
2
Untuk mendapatkan kembali data: Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
Eric Leschinski
1
Ini dapat dengan cepat menjadi tidak layak untuk POJO besar. Alih-alih menggunakan Bus. Lihat posting saya di bawah ini.
Steven Mark Ford
seperti yang saya sebutkan dalam jawaban saya, ini untuk penggunaan sederhana di mana Anda tidak membutuhkan objek itu sendiri, tetapi hanya beberapa nilai saja. Bukan untuk menjadi solusi untuk penggunaan kompleks.
MJB
1
Ide bagus untuk melewatkan satu objek, tapi saya mencoba untuk melewatkan array ukuran yang tidak diketahui dari objek saya. Mungkin solusi Anda bukan untuk melewati array objek.
Muhammad Saqib
25

Saya membuat kelas pembantu tunggal yang memegang benda-benda sementara.

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

Alih-alih meletakkan objek Anda di dalam Intent, gunakan IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

Di dalam Aktivitas baru Anda, Anda bisa mendapatkan objek:

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

Ingatlah bahwa setelah dimuat, objek dihapus untuk menghindari referensi yang tidak perlu.

Roger Sanoli
sumber
1
Ide bagus! Selain itu, Anda dapat membuat kelas tambahan ObjectContainer {Object, obj; boolean permanen; ....} Ide adalah bahwa, Anda dapat memberikan boolean dalam metode add jika Anda perlu menjaga objek tetap dan tidak menghapus ketika kita memanggil get. Ini akan membantu menjaga beberapa objek global. Seperti mungkin koneksi Bluetooth terbuka dll.
Umair
1
Lucu tapi jangan menciptakan kembali roda. Pola bus elegan dan lebih kuat. Lihat posting saya di bawah ini.
Steven Mark Ford
@StevenMarkFord, jadi apakah pola Bus masih berlaku sampai hari ini? Saya mencoba untuk meningkatkan basis kode dengan kode seperti ini mengakses data antara kegiatan: BookActivity.getInstance().recommendationResponsediRoomsActivity
Woppi
Ketika Aktivitas penerima dibuat ulang (misalnya pada rotasi layar) objmenjadi null. Untuk menghindarinya, objsebaiknya disimpan di suatu tempat untuk mendapatkannya kembali. Memang solusi Json menyimpan data objek di Intent.
Salvador
25

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 dapat menyimpan data umum dapat dinamai sebagai Common Utilities. Tergantung kamu.

E. Melewati data melalui Intents dan Interface Parcelable.

Itu tergantung pada kebutuhan proyek Anda.

A. Basis Data

SQLite adalah database sumber terbuka yang tertanam ke Android. SQLite mendukung fitur basis data relasional standar seperti sintaks SQL, transaksi, dan pernyataan yang disiapkan.

Tutorial

B. Preferensi bersama

Misalkan Anda ingin menyimpan nama pengguna. Jadi sekarang akan ada dua hal, nama pengguna utama , nilai nilai.

Cara menyimpan

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

Menggunakan putString (), putBoolean (), putInt (), putFloat (), dan 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

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

Gunakan kacang Jawa dan simpan di dalamnya sebagai salah satu ladangnya 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 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, tipe informasi dan byte yang mewakili objek dan datanya dapat digunakan untuk membuat ulang objek dalam memori.

Jika Anda ingin tutorial untuk ini lihat:

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 niat

Silakan lihat tutorial Android - Data paket untuk melewati antara Aktivitas menggunakan kelas Parcelable untuk opsi pengiriman data ini.

Nikhil Agrawal
sumber
22

Buat kelas Anda sendiri Customersebagai berikut:

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

}

Dalam onCreate()metode Anda

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

Di xyz activitykelas Anda perlu menggunakan kode berikut:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
Mayur Chudasama
sumber
..Periksa kode Anda, Anda memberikan "bundel" sebagai kunci untuk menempatkan objek cust & dapatkan dari "kelas" ..silakan gunakan satu kunci baik "kelas" atau "bundel" ..
AK Joshi
Saya menghadapi Kesalahan: Paket yang ditemui IOException menulis objek serial
Arul Mani
15

Cara terbaik adalah memiliki kelas (sebut saja Kontrol) di aplikasi Anda yang akan menampung variabel statis tipe 'Pelanggan' (dalam kasus Anda). Inisialisasi variabel dalam Aktivitas Anda A.

Sebagai contoh:

Control.Customer = CustomerClass;

Lalu pergi ke Aktivitas B dan ambil dari kelas Kontrol. Jangan lupa untuk menetapkan nol setelah menggunakan variabel, jika tidak memori akan terbuang.

Umesh
sumber
4
@ Aez Karena ceroboh dari sudut pandang desain dan akan pecah mengerikan jika Intent pernah dalam proses lain.
7
Anda akan mengalami masalah saat melanjutkan aplikasi ke Aktivitas B. Karena Aktivitas dapat dibunuh oleh Android dan objek tidak akan disimpan.
Ryan R
15
public class MyClass implements Serializable{
    Here is your instance variable
}

Sekarang Anda ingin meneruskan objek kelas ini di startActivity. Cukup gunakan ini:

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

Ini berfungsi di sini karena MyClass mengimplementasikan Serializable.

Dhiral Pandya
sumber
dapatkah Anda menjelaskan atau menguraikan lebih lanjut
Amitsharma
HomeworkData homeworkData = homeWorksList.get (posisi); Intent intent = Intent baru (c, HomeWorkActivitydetail.class); Bundel b = Bundel baru (); b.putSerializable ("CompleteData", homeworkData); intent.putExtras (b); c.startActivity (niat); pada saat menambahkan objek memberi saya beberapa kesalahan untuk menambahkan elemen objek tidak bisa kita melewati objek lengkap dengan ini
Amitsharma
di dalam homeworkData saya memiliki beberapa nilai yang ditambahkan
Amitsharma
12

Jika Anda memilih menggunakan cara yang dijelaskan Samuh, ingatlah bahwa hanya nilai primitif yang dapat dikirim. Yaitu, nilai-nilai yang parcable. Jadi, jika objek Anda berisi objek kompleks ini tidak akan mengikuti. Sebagai contoh, variabel seperti Bitmap, HashMap dll ... Ini sulit untuk dilewati dengan niat.

Secara umum saya akan saran Anda untuk mengirim tipe data hanya primitif sebagai tambahan, seperti String, int, boolean dll Dalam kasus Anda akan: String fname, String lname, int age, dan String address.

Pendapat saya: Objek yang lebih kompleks lebih baik dibagikan dengan menerapkan ContentProvider , SDCard , dll. Ini juga memungkinkan untuk menggunakan variabel statis , tetapi ini dapat dengan cepat menyebabkan kode rawan kesalahan ...

Tapi sekali lagi, ini hanya pendapat subjektif saya.

Vidar Vestnes
sumber
8

Saya menggunakan parcelable untuk mengirim data dari satu aktivitas ke aktivitas lainnya. Ini kode saya yang berfungsi dengan baik dalam proyek saya.

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

Dalam aktivitas, gunakan seperti ini:

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

Di ActivityB gunakan seperti ini untuk mendapatkan data:

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

Anda dapat mencoba menggunakan kelas itu. Batasannya adalah tidak dapat digunakan di luar satu proses.

Satu kegiatan:

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

Aktivitas lain:

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);
    }
}
Barbariska
sumber
6

Mulai aktivitas lain dari aktivitas ini dan berikan parameter melalui Bundle Object

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

Retrive data pada aktivitas lain (YourActivity)

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

Ini ok untuk jenis tipe data sederhana. Tetapi jika Anda ingin meneruskan data yang kompleks di antara aktivitas. Anda perlu membuat cerita bersambung 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);
DroidNinja
sumber
TypeToken <> sudah usang. Apa alternatifnya?
Ragavendra M
6

Pertanyaan ini juga dibahas dalam pertanyaan Stack Overflow lainnya. Silakan lihat solusi untuk Melewati data melalui niat menggunakan Serializable . Poin utama adalah tentang menggunakan Bundleobjek yang menyimpan data yang diperlukan di dalamnya Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

Untuk mengekstrak nilai:

 Bundle bundle = new Bundle();

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

Keuntungan dari Serializablekesederhanaannya. Namun, Anda harus mempertimbangkan menggunakan Parcelablemetode jika Anda memerlukan banyak data untuk ditransfer, karena Parcelabledirancang khusus untuk Android dan lebih efisien daripada Serializable. Anda dapat membuat Parcelablekelas menggunakan:

  1. alat online - parcelabler
  2. sebuah plugin untuk Android Studio - generator kode Android Parcelable
Ayaz Alifov
sumber
5

Krak kelas seperti kelas kacang dan mengimplementasikan Serializableantarmuka. Kemudian kita bisa meneruskannya melalui intentmetode, misalnya:

intent.putExtra("class", BeanClass);

Kemudian dapatkan dari aktivitas lain, misalnya:

BeanClass cb = intent.getSerializableExtra("class");
Peter Mortensen
sumber
5

Buat dua metode di Kelas khusus Anda seperti ini

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

Sekarang di pengirim Anda Kegiatan lakukan seperti ini

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

Dan di Aktivitas penerima Anda

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

Ya, menggunakan objek statis sejauh ini merupakan cara termudah untuk melakukan ini dengan objek non-serialis khusus.

Alistair
sumber
Ya, saya pikir saya benar-benar setuju dengan Anda. Membuat objek-objek itu staticadalah solusi yang lebih baik jika tidak praktis untuk terus memohon putExtra()setiap properti yang ingin Anda sampaikan. Misalnya, sekarang, saya ingin meneruskan ArrayListyang berisi objek. Saya mungkin juga membuat ArrayList saya staticsebagai gantinya.
Matthew Quiros
3

Objek Aktivitas Android dapat dihancurkan dan disusun kembali. Jadi, Anda perlu menggunakan pendekatan lain untuk melihatnya - atau objek apa pun yang mereka buat !!! - naik. Artinya, Anda bisa lulus sebagai referensi kelas statis tetapi kemudian pegangan objek (Java menyebut ini "referensi", seperti halnya SmallTalk; tetapi mereka bukan referensi dalam arti C atau rakitan) akan mungkin tidak valid nantinya karena "fitur" Android OE adalah Kegiatan apa pun dapat dimusnahkan dan dilarutkan nanti.

Pertanyaan asli bertanya "Bagaimana cara meneruskan objek dari satu aktivitas ke aktivitas lainnya di Android" dan tidak ada yang menjawabnya. Yang pasti, Anda bisa membuat serial (Serializable, Parcelable, ke / dari JSON) dan meneruskan salinan data objek dan objek baru yang memiliki data yang sama dapat dibuat; tetapi TIDAK akan memiliki referensi / pegangan yang sama. Juga, banyak orang lain menyebutkan Anda dapat menyimpan referensi di toko statis. Dan itu akan berfungsi kecuali Android memutuskan untuk Menghancurkan Aktivitas Anda.

Jadi, untuk benar-benar menyelesaikan pertanyaan awal Anda akan memerlukan pencarian statis ditambah setiap objek akan memperbarui referensi ketika / jika itu dibuat ulang. Misalnya setiap Aktivitas Android akan mencatat ulang dirinya sendiri jika onCreate disebut. Anda juga dapat melihat bagaimana beberapa orang menggunakan daftar tugas untuk mencari Kegiatan berdasarkan nama. (sistem sementara menghancurkan instance aktivitas ini untuk menghemat ruang..getRunningTasks, daftar tugas secara efektif merupakan daftar khusus instance objek terbaru dari setiap Aktivitas).

Sebagai referensi:

Berhenti: "Aktivitas ini sepenuhnya dikaburkan oleh aktivitas lain (aktivitas sekarang dalam" latar belakang "). Aktivitas yang dihentikan juga masih hidup ( objek Aktivitas disimpan dalam memori , ia menyimpan semua informasi status dan anggota, tetapi tidak terpasang ke manajer jendela). Namun, itu tidak lagi terlihat oleh pengguna dan dapat dibunuh oleh sistem ketika memori diperlukan di tempat lain. "

onDestroy "sistem sementara menghancurkan instance dari aktivitas ini untuk menghemat ruang."

Jadi, Bus Pesan adalah solusi yang bisa diterapkan. Ini pada dasarnya "punts". Alih-alih mencoba untuk memiliki referensi ke objek; lalu Anda mendesain ulang desain Anda untuk menggunakan MessagePassing alih-alih SequentialCode. Secara eksponensial lebih sulit untuk di-debug; tetapi itu memungkinkan Anda mengabaikan pemahaman OperatingEnvironment semacam ini. Secara efektif, setiap akses metode objek dibalik sehingga pemanggil memposting Pesan dan objek itu sendiri mendefinisikan penangan untuk pesan itu. Banyak lagi kode tetapi dapat membuatnya kuat dengan batasan Android OE.

Jika semua yang Anda inginkan adalah Aktivitas teratas (hal yang biasa di aplikasi Android karena "Konteks" diperlukan di mana-mana), maka Anda bisa meminta setiap Aktivitas mencantumkan dirinya sebagai "teratas" di ruang global statis setiap kali onResume disebut. Maka AlertDialog Anda atau apa pun yang membutuhkan konteks dapat langsung mengambilnya dari sana. Juga, ini agak kurang beruntung untuk menggunakan global tetapi dapat menyederhanakan menyampaikan suatu Konteks ke atas dan ke bawah di mana-mana dan, tentu saja, ketika Anda menggunakan MessageBus maka IT IS global.

TimJowers2
sumber
Otto memiliki pro untuk dapat menjalankannya secara eksternal hanya dalam aplikasi Java biasa. Jadi, bagus untuk dev dan pengujian tanpa harus main-main dengan Android. Otto memiliki banyak kurva pembelajaran besar dan sebagian besar solusinya telah dipecahkan dengan cara Android (siaran lokal, dll) atau dalam pendekatan pengembang aplikasi normal (Anda dapat menulis pencarian global yang jauh lebih sederhana daripada pencarian global Otto, pendekatan normal jauh lebih mudah didekati untuk vectoring / F3 melalui kode dan untuk melangkah melalui debugging).
TimJowers2
2
  1. Saya tahu statis itu buruk, tetapi sepertinya kami terpaksa menggunakannya di sini. Masalah dengan parceables / seriazables adalah bahwa kedua aktivitas memiliki instance duplikat dari objek yang sama = pemborosan memori dan CPU.

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

Aktivitas menelepon

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

Aktivitas yang dipanggil (perhatikan bahwa onCreate () dan onResume () dapat dipanggil beberapa kali ketika sistem menghancurkan dan membuat ulang aktivitas)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Cara lain adalah dengan mendeklarasikan bidang statis kelas yang ingin Anda sampaikan di kelas itu. Itu hanya akan melayani untuk tujuan ini. Jangan lupa itu bisa null di onCreate, karena paket aplikasi Anda telah diturunkan dari memori oleh sistem dan dimuat ulang nanti.

  2. Ingatlah bahwa Anda masih perlu menangani siklus hidup aktivitas, Anda mungkin ingin menulis semua data langsung ke preferensi bersama, menyakitkan dengan struktur data yang kompleks seperti itu.

Anton Duzenko
sumber
1

Di atas jawaban hampir semuanya benar, tetapi bagi mereka yang tidak memahami dan menjawabnya, Android memiliki kelas yang kuat. Maksudnya , Anda membagikan data antara tidak hanya aktivitas tetapi juga komponen Android lainnya (penerima broadcasr, servis untuk konten, asalkan kami menggunakan kelas ContetnResolver no Intent ). Dalam aktivitas Anda, Anda membangun niat

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

Dalam aktivitas receving yang Anda miliki

public class SomeActivity extends AppCompactActivity {

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

}

Anda harus mengimplementasikan antarmuka Parceable atau Serializable pada objek Anda untuk berbagi antar kegiatan. Sulit untuk mengimplementasikan Parcealbe daripada antarmuka Serializable pada objek itu sebabnya Android memiliki plugin terutama untuk ini. Unduh dan gunakan

dara
sumber
0

Saya selalu bertanya-tanya mengapa ini tidak sesederhana memanggil metode kegiatan lain. Baru-baru ini saya menulis perpustakaan utilitas yang membuatnya hampir sesederhana itu. Anda dapat memeriksanya di sini ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).

GNLauncher membuat pengiriman objek / data ke suatu Aktivitas dari Aktivitas lain, dll. Semudah memanggil fungsi dalam Aktivitas dengan data yang diperlukan sebagai parameter. Ini memperkenalkan keamanan jenis dan menghilangkan semua kesibukan karena harus membuat cerita bersambung, melekat pada maksud menggunakan kunci string dan membatalkan yang sama di ujung lainnya.

Pemakaian

Tetapkan antarmuka dengan metode yang ingin Anda panggil pada Aktivitas untuk diluncurkan.

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

Implementasikan antarmuka di atas pada Activity untuk diluncurkan. Juga beri tahu GNLauncher ketika aktivitas siap.

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 Aktivitas lain, dapatkan proxy ke Aktivitas di atas dan panggil metode apa pun dengan parameter yang diinginkan.

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

Aktivitas pertama akan diluncurkan dan metode dipanggil dengan parameter yang diperlukan.

Prasyarat

Silakan merujuk ke https://github.com/noxiouswinter/gnlib_android/wiki#prasyarat untuk informasi tentang cara menambahkan dependensi.

jinais
sumber
0

Mengirim objek dari satu aktivitas ke aktivitas lain.

(1) aktivitas sumber

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

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

(2) aktivitas tujuan

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

Saya biasa mengatur objek dengan Pacelable atau Serializable untuk mentransfer, tetapi setiap kali saya menambahkan variabel lain ke objek (model), saya harus mendaftarkan semuanya. Sangat tidak nyaman.

Sangat mudah untuk mentransfer objek antara aktivitas atau fragmen.

Android DataCache

Kimkevin
sumber
0

Kita dapat meneruskan objek dari satu aktivitas ke aktivitas lain:

SupplierDetails poSuppliersDetails = new SupplierDetails();

Di dalam poSuppliersDetailskita memiliki beberapa nilai. Sekarang saya mengirim objek ini ke aktivitas target:

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

Cara mendapatkan ini di ACtivityTwo:

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");
Peter Mortensen
sumber
0

Berikan satu aktivitas ke aktivitas lain:

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

Dapatkan nilai:

String myvalue= getIntent().getExtras("passingkey");
Bhuvaneshwaran Vellingiri
sumber
-1

Halo semua, saya melihat banyak opsi bagus tapi saya bertanya-tanya mengapa Binding belum digunakan?

Melewati referensi ke suatu objek tampaknya lebih efisien bagi saya daripada membuat serial dan objek desterilisasi, tapi saya belum melakukan penyelaman mendalam untuk melihat apakah itu yang terjadi di balik layar.

Membuat Binder cukup sederhana ...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

Dan menciptakan parcelable untuk menggunakannya bukanlah eter yang buruk.

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

    };
}

Logika ini sangat keren karena Anda benar-benar memberikan referensi dari aktivitas ke aktivitas.

Saya akan menyarankan memeriksa nol dan jika instance dari Binder adalah MyBinder!

dan untuk menerapkan ini, Anda hanya ...

Kirimkan itu

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

intent.putExtra("MyParcelable", myParcelable);

Mendapatkannya kembali

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

Heck seseorang bisa jadi gila dan membuat pengisap ini benar-benar generik.

SkidRunner
sumber