Как отправить объект из одного действия Android в другое с помощью намерений?

Как передать объект настраиваемого типа из одного Activity в другой используя метод putExtra() класса Intent?


person Community    schedule 26.01.2010    source источник
comment
@UMMA - вам не нужно постоянно отмечать свои вопросы как Community Wiki. Посмотрите здесь: meta.stackexchange.com/questions/11740/   -  person Dave Webb    schedule 26.01.2010
comment
@Paresh: указанная вами ссылка не работает. не могли бы вы предоставить альтернативу?   -  person antiplex    schedule 25.01.2012
comment
возможный дубликат Как передать объект из одного действия другому в Android   -  person luke    schedule 01.05.2013
comment
Ознакомьтесь с этим ответом. stackoverflow.com/questions/8857546/   -  person Heitor Colangelo    schedule 18.09.2015
comment
я нашел простой и элегантный метод stackoverflow.com/a/37774966/6456129   -  person Yessy    schedule 12.06.2016


Ответы (33)


Если вы просто передаете объекты, то для этого был разработан Parcelable. Это требует немного больше усилий, чем использование собственной сериализации Java, но это намного быстрее (и я имею в виду, WAY быстрее).

Из документации простой пример реализации:

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

Обратите внимание, что в случае, если у вас есть более одного поля для извлечения из данной посылки, вы должны сделать это в том же порядке, в котором вы их помещали (то есть в подходе FIFO).

После того, как ваши объекты реализуют Parcelable, остается просто поместить их в свои намерения с putExtra ():

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

Затем вы можете вернуть их с помощью getParcelableExtra ():

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

Если ваш объектный класс реализует Parcelable и Serializable, убедитесь, что вы выполняете приведение к одному из следующих вариантов:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
person Community    schedule 26.01.2010
comment
Как это будет реализовано, если mData является объектом (например, JSONObject), а не int? - person Peter Ajtai; 02.11.2011
comment
В Parcel есть и другие методы для записи типов данных, например строк. В случае JSONObject вы можете вернуть его в JSON и записать в виде строки. Если объект является сериализуемым, и у вас нет доступа, чтобы сделать его Parcelable, возможно, вы могли бы сериализовать его и десериализовать, когда вы распаковываете объект верхнего уровня? Я не делал этого раньше, просто предположение. - person Rob Lourens; 02.11.2011
comment
Почему нельзя просто передать объект без всего этого? Мы хотим передать объект, который уже находится в памяти. - person ceklock; 04.06.2012
comment
@tecnotron, потому что его приложения находятся в разных процессах и имеют отдельные адресные пространства памяти, вы не можете просто отправить указатель (ссылку) на блок памяти в своем процессе и ожидать, что он будет доступен в другом процессе. - person marcinj; 21.06.2012
comment
Что мне делать, если я не могу сделать класс объекта сериализуемым или Parceable? - person Amel Jose; 27.06.2012
comment
@ Амель, можешь привести пример? - person Jeremy Logan; 19.10.2012
comment
@PeterAjtai Вы можете использовать out.writeString для записи строки и т. Д. - person poiuytrez; 22.01.2013
comment
плохой дизайн, просто скажи - person Leo; 13.11.2013
comment
это не работает. см. code.google.com/p/android/issues/ - person likejudo; 12.03.2014
comment
@ceklock причина этого заключается в следующем: когда действие идет позади и позже удаляется из памяти, а затем, когда пользователь открывает его из меню недавних событий, он должен создать действие там, где оно было остановлено. Пользовательский интерфейс должен быть таким же. В этом случае объекта нет в памяти. Но цель такая. - person tasomaniac; 20.03.2014
comment
@ceklock, потому что он почти всегда настаивает на статическом поле где-то - лучший способ получить утечки в ваше приложение - person martyglaubitz; 11.06.2014
comment
И вы можете сделать то же самое с Serializable, но он будет работать намного быстрее. Проверьте этот образец проекта: bitbucket.org/afrishman/androidserializationtest - person afrish; 29.03.2015
comment
Генератор полей для участков: www.parcelabler.com из stackoverflow.com/a/26757130/1277350 - person LordParsley; 23.07.2015
comment
Проблема с этим подходом заключается в том, что у вас может быть только parcable объект с атрибутами SIMPLE в нем (int, char, String). Вы не можете создать разделяемый объект с другими сложными объектами в качестве его свойств ... Для большей ясности просмотрите строку out.writeInt (mData); - person Pontios; 07.03.2016
comment
Я реализую Parcelable, но получаю ошибку, например, не могу упорядочить значение. почему я получаю эту ошибку? - person AMAN SINGH; 19.09.2016
comment
@Pontios Вы можете поместить другие Parcelable в Parcelable ... или что-нибудь, что поддерживает встроенную сериализацию Java. - person Jeremy Logan; 28.09.2016
comment
@JeremyLogan, как мне создать его объект, когда конструктор является частным? - person huskygrad; 25.10.2016
comment
Убедитесь, что в вашем pojo есть несколько внутренних классов, а затем реализуйте Parcelable во всех классах. - person Arpit Patel; 19.11.2016
comment
@Sanket static newInstance (), который вызывает конструктор? - person The incredible Jan; 21.09.2017
comment
Если вы передадите объект из Activity1 в Activity2, а затем измените объект в Activity2, ваши изменения не будут отображаться в Activity1. Это потому, что вы передаете копию данных объекта, а не ссылку на сам объект. - person AtomicBoolean; 03.04.2018
comment
Я использую Parcelable, но для Map ‹String, Object› я получаю сообщение об ошибке. Как использовать это в Parcelable - person Shyamaly Lakhadive; 17.04.2021

Вам нужно будет сериализовать ваш объект в какое-то строковое представление. Одним из возможных строковых представлений является JSON, а один из самых простых способов сериализации в / из JSON в Android, если вы спросите меня, - это Google GSON.

В этом случае вы просто помещаете строковое возвращаемое значение из (new Gson()).toJson(myObject);, извлекаете строковое значение и используете fromJson, чтобы превратить его обратно в свой объект.

Однако, если ваш объект не очень сложный, это может не стоить накладных расходов, и вместо этого вы можете рассмотреть возможность передачи отдельных значений объекта.

person Community    schedule 26.01.2010
comment
Я предполагаю, потому что ответ fiXedd решает ту же проблему без использования внешних библиотек способом, который просто настолько предпочтителен, что ни у кого не должно быть причин использовать решение, которое я предоставил (не зная, в то время, гениальное решение fiXedd) - person David Hedlund; 14.04.2010
comment
Думаю, это правильно. Кроме того, JSON является протоколом, более подходящим для клиент-серверной, а не поточной передачи. - person mobibob; 16.08.2010
comment
Не обязательно плохая идея, особенно. поскольку Gson намного проще использовать, чем реализовать parcelable для всех объектов, которые вы хотите отправить. - person uvesten; 13.04.2011
comment
поскольку я использую gson в своем приложении, это действительно простой и приятный способ! - person Lars; 08.12.2011
comment
для удобства во многих приложениях подход GSON выигрывает, если производительность не является приоритетом. Его быстрее кодировать, возможно, он уже используется где-то в вашем приложении, и его легче понять. Повышается ремонтопригодность кода. Так что вы получите +1 за ваш ответ CW. - person Richard Le Mesurier; 22.02.2014
comment
Хороший ответ, хотя полное решение было бы String s = (new Gson().toJson(client));, а затем Cli client = new Gson().fromJson(s, Cli.class); - person Joaquin Iurchuk; 02.01.2015
comment
+1 к этому решению. Я совершенно забыл, что я уже использовал Gson для использования с Retrofit, и это делает вещи в миллион раз проще, чем реализация Parcelable для каждого отдельного объекта. Gson абсолютно заслуживает использования, если вы делаете что-нибудь с веб-API / библиотеками, такими как Retrofit, потому что это буквально 2 строки кода для добавления или получения Intent дополнительных услуг. Я добавлю (@mobibob), что JSON - это просто формат обмена данными, а преобразование объектов в строки JSON для отправки между потоками (как это уже делает Intent.putExtra()), на мой взгляд, более или менее похоже на клиент / сервер. - person Chris Cirefice; 24.06.2015
comment

Вы можете отправить сериализуемый объект через намерение

// 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 {
} 
person Community    schedule 13.09.2012
comment
вы также можете отправлять объекты Parcelable через намерение. - person tony gil; 21.03.2013
comment
Serializable до смешного медленный на Android. Фактически, граница во многих случаях бесполезна. посмотрите http://stackoverflow.com/questions/5550670/benefit-of-using-parcelable-instead-of-serializing-object - person Seraphim's; 19.11.2013
comment
что, если действие уже запущено, нужно ли выполнять startActivity (i); ? Я имею в виду, могу ли я сделать так, чтобы действие A вызвало действие B, и оно вернет данные в действие A? я в замешательстве? - person Francisco Corrales Morales; 09.05.2014
comment
Производительность @ Seraphim имеет значение, если вы сериализуете много объектов, но пользователь не заметит, если сериализация одного объекта занимает 1 мс или 10 мс. Если дополнительное намерение уже Serializable, но не Parcelable, редко стоит тратить время на его создание Parcelable. - person Kevin Krumwiede; 01.07.2015

В ситуациях, когда вы знаете, что будете передавать данные в приложении, используйте «глобальные переменные» (например, статические классы).

Вот что Дайан Хакборн (hackbod - инженер-программист Google Android) сказала по этому поводу:

В ситуациях, когда вы знаете, что действия выполняются в одном процессе, вы можете просто обмениваться данными через глобальные объекты. Например, у вас может быть глобальный HashMap<String, WeakReference<MyInterpreterState>>, и когда вы создаете новое MyInterpreterState, придумайте для него уникальное имя и поместите его в хэш-карту; чтобы отправить это состояние другому действию, просто поместите уникальное имя в хэш-карту, и когда второе действие будет запущено, оно сможет получить MyInterpreterState из хэш-карты с полученным именем.

person Community    schedule 02.11.2011
comment
да, мне показалось странным, что нам дают использовать эти намерения, а затем ведущий инженер говорит нам просто использовать глобальные переменные для наших данных. Но там это прямо изо рта лошади. - person Richard Le Mesurier; 22.02.2014
comment
Разве слабые ссылки здесь не станут жертвой сборки мусора? - person uLYsseus; 23.11.2014
comment
@uLYsseus думает, что это идея, как только вы закончите с ними в действиях ... поэтому, когда соответствующие действия будут уничтожены, он позволит gc - person Peter Ajtai; 26.11.2014
comment
@RichardLeMesurier Я думал о том же, но затем я просмотрел упомянутый выше пост в группах Google от Дайан Хакборн, и она упоминает, что на самом деле единственная проблема с глобальными переменными будет возникать при использовании неявных намерений (которые могут запускать действие вне вашего пакета ). Как отмечает Дайанн, это имеет смысл, потому что эти действия, скорее всего, не будут знать о настраиваемых типах, которые вы им передаете. Как только я это прочитал, мне стало понятнее, почему глобальные переменные могут быть не таким уж плохим маршрутом в данных обстоятельствах, и я решил, что поделюсь, если другим тоже будет любопытно. - person BMB; 18.03.2016
comment
Намерения были переработаны до такой степени, что их можно было передать на другой компьютер. что, очевидно, не лучший способ что-либо делать, когда у вас есть только один процесс, в котором вы возитесь. Причины, по которым это нехорошо: использование памяти, использование процессора, использование батареи. последний особенно сделал выбор дизайна с намерениями, довольно запутанными в ретроспективе. есть люди, которые настаивают на том, что это хорошая идея, обычно потому, что так сказал Google. - person Lassi Kinnunen; 01.03.2018

Ваш класс должен реализовывать Serializable или Parcelable.

public class MY_CLASS implements Serializable

После этого вы можете отправить объект на putExtra.

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Чтобы получить дополнительные услуги, вам нужно всего лишь сделать

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

Если ваш класс реализует Parcelable, используйте следующий

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

Надеюсь, это поможет: D

person Community    schedule 23.04.2013
comment
Ваш класс должен реализовать Serializable неверно. Например, класс может реализовать Parcelable. - person Marc Plano-Lesay; 02.10.2013
comment
в чем разница между Parcelable и Serializable @Kernald? Что касается времени обработки, это медленнее / не лучшая практика или что-то в этом роде? - person gumuruh; 17.07.2014
comment
В то время как Serializable является стандартным интерфейсом Java, Parcelable специфичен для Android. С точки зрения производительности Parcelable более эффективен: developerphil.com/parcelable-vs-serializable - person Marc Plano-Lesay; 17.07.2014

Краткий ответ для быстрой необходимости

1. Внедрите свой класс в сериализуемый.

Если у вас есть внутренние классы, не забудьте также реализовать их в Serializable !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Поместите свой объект в намерение

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

3. И получите свой объект в другом классе деятельности

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");
person Community    schedule 14.07.2017
comment
см. эту ссылку, stackoverflow.com/questions/2139134/ - person RejoylinLokeshwaran; 01.09.2017
comment
Вы можете добиться того же, реализовав интерфейс Parcelable. Интерфейс Parcelable требует больше времени для реализации по сравнению с интерфейсом Serializable из-за размера кода. Но он работает быстрее, чем Serializable, и использует меньше ресурсов. - person Kwnstantinos Nikoloutsos; 04.07.2018

реализовать сериализуемый в своем классе

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

Затем вы можете передать этот объект намеренно

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

во втором действии вы можете получить такие данные

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

Но когда объем данных станет большим, этот метод будет медленным.

person Community    schedule 22.09.2016

если ваш объектный класс реализует Serializable, вам не нужно ничего делать, вы можете передать сериализуемый объект.
вот что я использую.

person Community    schedule 07.08.2011

Есть несколько способов получить доступ к переменным или объектам в других классах или Activity.

A. База данных

Б. общие предпочтения.

C. Сериализация объекта.

D. Класс, который может хранить общие данные, может называться Common Utilities, это зависит от вас.

E. Передача данных через намерения и интерфейс Parcelable.

Это зависит от потребностей вашего проекта.

A. База данных

SQLite - это база данных с открытым исходным кодом, встроенная в Android. SQLite поддерживает стандартные функции реляционной базы данных, такие как синтаксис SQL, транзакции и подготовленные операторы.

Учебники - http://www.vogella.com/articles/AndroidSQLite/article.html

Б. Общие настройки

Предположим, вы хотите сохранить имя пользователя. Таким образом, теперь будет две вещи: Ключевое имя пользователя и Значение.

Как хранить

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

Используя putString (), putBoolean (), putInt (), putFloat (), putLong (), вы можете сохранить желаемый тип данных.

Как получить

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

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

C. Сериализация объекта

Сериализация объекта используется, если мы хотим сохранить состояние объекта, чтобы отправить его по сети, или вы также можете использовать его для своих целей.

Используйте java beans и сохраните его как одно из его полей и используйте для этого геттеры и сеттеры

JavaBeans - это классы Java, у которых есть свойства. Думайте о свойствах как о частных переменных экземпляра. Поскольку они являются частными, единственный способ получить к ним доступ извне своего класса - это использовать методы в классе. Методы, которые изменяют значение свойства, называются методами установки, а методы, которые получают значение свойства, называются методами получения.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

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


}

Установите переменную в вашем почтовом методе, используя

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

Затем используйте сериализацию объекта для сериализации этого объекта и десериализации этого объекта в другом классе.

При сериализации объект может быть представлен как последовательность байтов, которая включает данные объекта, а также информацию о типе объекта и типах данных, хранящихся в объекте.

После того, как сериализованный объект был записан в файл, он может быть прочитан из файла и десериализован, то есть информация о типе и байты, которые представляют объект и его данные, могут быть использованы для воссоздания объекта в памяти.

Если вам нужен учебник по этой ссылке

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

Получить переменную в других классах

D. CommonUtilities

Вы можете сами создать класс, который может содержать общие данные, которые вам часто нужны в вашем проекте.

Образец

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Передача данных через намерения

Пожалуйста, обратитесь к этому руководству для этой опции передачи данных.

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

person Community    schedule 25.06.2013
comment
Хороший учебник, который вы упомянули в (E) по передаче данных через намерения. - person remrick; 07.04.2015

Для этого вы можете использовать Android BUNDLE.

Создайте Bundle из своего класса, например:

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

    return b;
}

Затем передайте этот комплект с НАМЕРЕНИЕМ. Теперь вы можете воссоздать свой объект класса, передав пакет, например

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

Объявите это в своем пользовательском классе и используйте.

person Community    schedule 27.03.2011
comment
Предпочтительнее прямая реализация Parcelable, ИМХО. Bundle реализует Parcelable сам по себе, так что вы по-прежнему получаете прирост производительности, избегая при этом проблем с его самостоятельной реализацией. Вместо этого вы можете использовать пары ключ-значение для хранения и извлечения данных, что намного надежнее, чем полагаться на простой порядок. - person Risadinha; 06.05.2013
comment
Parcelable кажется мне сложным, в моем приведенном выше ответе я использую метод toBundle из класса для этого объекта, поэтому объект преобразуется в пакет, а затем мы можем использовать конструктор для преобразования пакета в объект класса. - person om252345; 08.05.2013
comment
Это решение жизнеспособно, только если вы передаете один объект через намерение. - person TheIT; 08.08.2014
comment
Как json, но я думаю, что json легкий. - person David; 27.08.2015
comment
Будет ли объект, когда я его получу, тем же самым объектом или его копией? - person Markus; 11.02.2016
comment
Это решает проблему, потому что я думаю, они сказали, как передать объект, а не строку - person blackHawk; 28.05.2017

Спасибо за посылочную помощь, но я нашел еще одно дополнительное решение

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

В первом действии

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

Получить данные в действии 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());
        }
person Community    schedule 05.04.2012
comment
хороший ответ, но повысьте свои стандарты кодирования ... +1 хотя за то, что Serializable участвует в соревнованиях, однако Parcellables намного быстрее ... - person Amit; 29.05.2012

Я использую Gson с его мощным и простым API для отправки объектов между действиями,

Пример

// 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 функции, которые вы добавляете к объектам, которые хотите отправить

Использование

Отправить объект из пункта А в пункт Б

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

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

Получить в B

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

Я использую его почти в каждом проекте, и у меня нет проблем с производительностью.

person Community    schedule 26.02.2016
comment
Спасибо, это избавило меня от лишних сложностей. - person Hristo Stoyanov; 13.02.2018

Я боролся с той же проблемой. Я решил это, используя статический класс, сохраняя любые данные, которые я хочу, в HashMap. Сверху я использую расширение стандартного класса Activity, в котором я переопределил методы onCreate и onDestroy, чтобы скрыть перенос данных и очистку данных. Приходится менять какие-то нелепые настройки, например ориентация-обработка.

Аннотация: Не предоставлять общие объекты для передачи другому Activity - заноза в заднице. Это как выстрелить себе в колено и надеяться выиграть 100 метров. «Паркабель» не является достаточной заменой. Это заставляет меня смеяться ... Я не хочу внедрять этот интерфейс в свой свободный от технологий API, поскольку я меньше хочу вводить новый уровень ... Как это может быть, что мы находимся в мобильном программировании так далеко от современная парадигма ...

person Community    schedule 10.09.2012

В вашем первом действии:

intent.putExtra("myTag", yourObject);

А во втором:

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

Не забудьте сделать свой настраиваемый объект сериализуемым:

public class myCustomObject implements Serializable {
...
}
person Community    schedule 19.10.2013
comment
Parcelable лучше, чем Serializable! Избегайте использования Serializable в вашем коде Android! - person Filipe Brito; 06.07.2015

Другой способ сделать это - использовать объект Application (android.app.Application). Вы определяете это в своем AndroidManifest.xml файле как:

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

Затем вы можете вызвать это из любого действия и сохранить объект в классе Application.

В FirstActivity:

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

В SecondActivity выполните:

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

Это удобно, если у вас есть объекты, которые имеют область действия на уровне приложения, т.е. они должны использоваться во всем приложении. Метод Parcelable все же лучше, если вы хотите явный контроль над областью объекта или если область ограничена.

Тем не менее, это позволяет полностью избежать использования Intents. Не знаю, подходят ли они вам. Другой способ, который я использовал, - это int идентификаторов объектов, отправляемых через намерения, и получение объектов, которые у меня есть в Картах в объекте Application.

person Community    schedule 18.12.2012
comment
Это неправильный способ делать что-то, поскольку объекты могут быть переменными, ваш может работать, если вы говорите о статическом объекте на протяжении жизненного цикла приложения, но иногда нам нужны пассивные объекты, которые могут быть сгенерированы с помощью веб-службы или так stackoverflow.com/a/2736612/716865 - person Muhannad A.Alhariri; 01.05.2013
comment
Я успешно использовал его с объектами, созданными из веб-сервисов, имея область приложения Map, в которой объекты хранятся и извлекаются с использованием идентификатора. Единственная реальная проблема с этим подходом заключается в том, что Android через некоторое время очищает память, поэтому вам нужно проверить наличие нулей в своем onResume (я думаю, что объекты, переданные в намерениях, сохраняются, но я не уверен). Кроме того, я не считаю это значительно хуже. - person Saad Farooq; 02.05.2013
comment
Это лучший ответ. Он показывает, как разные действия могут ссылаться на одну и ту же модель данных. Мне потребовалось много времени, чтобы это обнаружить! - person Markus; 11.02.2016

в вашей модели класса (Object) реализуйте Serializable, например:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

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


}

и ваше первое действие

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

и ваше второе действие (NewActivity)

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

удачи!!

person Community    schedule 26.08.2015

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

}

Передача данных:

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

Получение данных:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
person Community    schedule 08.01.2016

Самое простое решение, которое я нашел, - это создать класс со статическими элементами данных с установщиками геттеров.

установить из одного действия и получить из другого действия этот объект.

деятельность А

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

деятельность b

mytestclass obj= mytestclass.staticfunctionGet();
person Community    schedule 10.02.2010
comment
Этого недостаточно для поддержки произвольного класса. Что вы собираетесь делать, если в настраиваемом объекте есть ссылка на файл? Вы хотите передать имя или обработать контент? Parcelable предоставит одну из таких опций через настройки флага. - person mobibob; 16.08.2010
comment
или сериализуемый класс creata для передачи другому действию того, что вы хотите передать. - person UMAR-MOBITSOLUTIONS; 09.05.2011
comment
Только помните, что нельзя класть большие толстые предметы. Время жизни этого объекта будет таким же, как время жизни приложения. И никогда не храните просмотры. Этот метод также гарантирует утечку памяти. - person Reno; 17.09.2011
comment
Этот ответ полезен, но не является лучшим решением с точки зрения оптимизации памяти и ресурсов. - person Atul Bhardwaj; 13.07.2012
comment
этот ответ не имеет для меня смысла - статическая функция может обращаться только к статическим членам - как вы передадите нестатические члены? - person likejudo; 30.03.2014
comment
Это нарушает принципы ООП, вводя глобальные переменные. Вы никогда не знаете, в каком состоянии они находятся, установлены они или нет, они используются многими потоками, и вам придется иметь дело с этой сложностью. Обычно это хорошая утечка памяти, потому что вы даже не знаете, когда освободить эти переменные. Нельзя сказать, что он вводит жесткую прямую связь между различными модулями приложения. - person afrish; 27.07.2014
comment
Какого черта? Два других ответа намного лучше. - person IcyFlame; 11.05.2016
comment
@IcyFlame в основном OP ответил на свой вопрос и принял его, хотя другие ответы намного лучше. веселье - person Varun; 13.10.2016
comment
GSON, parcelable и serializable - лучшие ответы, чем это на самом деле. - person Leontsev Anton; 26.10.2017

вы можете использовать методы putExtra (Serializable ..) и getSerializableExtra () для передачи и получения объектов вашего типа класса; вам нужно будет пометить свой класс как Serializable и убедиться, что все ваши переменные-члены тоже сериализуемы ...

person Community    schedule 06.10.2011

Создать приложение для Android

Файл >> Новый >> Приложение для Android

Введите название проекта: android-pass-object-to-activity

Паккейдж: com.hmkcode.android

Оставьте другие варианты по умолчанию, переходите "Далее", пока не дойдете до "Готово".

Перед тем, как приступить к созданию приложения, нам нужно создать класс POJO «Человек», который мы будем использовать для отправки объекта из одного действия в другое. Обратите внимание, что класс реализует интерфейс 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 + "]";
    }   
}

Два макета для двух занятий

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>

Два класса активности

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

}
}
person Community    schedule 27.11.2013

Используя библиотеку Google Gson, вы можете передавать объект другим действиям. Фактически мы преобразуем объект в виде строки json, а после перехода к другому действию мы снова повторно конвертируем в объект, подобный этому.

Рассмотрим такой класс bean-компонентов

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

Нам нужно передать объект класса Example

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

Для чтения нам нужно проделать обратную операцию в 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);

Добавьте эту зависимость в gradle

compile 'com.google.code.gson:gson:2.6.2'
person Community    schedule 07.09.2016

Я знаю, что это поздно, но это очень просто. Все, что у вас есть, это позволить вашему классу реализовать Serializable, например

public class MyClass implements Serializable{

}

тогда вы можете перейти к намерению, например

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

Чтобы получить это, вы просто позвоните

MyClass objec=(MyClass)intent.getExtra("theString");
person Community    schedule 13.08.2016

В Колтине

Добавьте расширение kotlin в свой build.gradle.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Затем создайте свой класс данных следующим образом.

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

Передать объект с намерением

val sample = Sample(1,"naveen")

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

Получить объект с намерением

val sample = intent.getParcelableExtra("id")
person Community    schedule 15.02.2019
comment
Это все еще экспериментально? - person ShadeToD; 28.06.2019

Если у вас есть одноэлементный класс (служба fx), действующий в любом случае как шлюз на уровень вашей модели, его можно решить, имея переменную в этом классе с геттерами и сеттерами для него.

В действии 1:

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

В действии 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.
}

В сервисе:

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

Это решение не требует какой-либо сериализации или другой «упаковки» рассматриваемого объекта. Но это будет полезно только в том случае, если вы все равно будете использовать такую ​​архитектуру.

person Community    schedule 24.06.2015
comment
Каковы недостатки этого подхода? Это кажется таким логичным и тонким. Я всегда читаю, что вы не должны этого делать, но я никогда не получаю хорошего объяснения того, что может пойти не так. - person Markus; 11.02.2016
comment
Поскольку я больше не могу редактировать свой комментарий: разве это не единственное возможное решение для получения ссылки на объект вместо копии? Мне нужно получить тот же объект, а не копию! - person Markus; 11.02.2016
comment
Я думаю, что это несколько обескураживает из-за высокой связи, к которой это приводит. Но да, насколько я понимаю, этот подход является наиболее жизнеспособным, если вам нужен реальный объект. Как всегда в программировании, вы можете делать все, что хотите, просто нужно делать это осторожно. Это решение сработало для меня, и я предпочитаю его, так как в любом случае использую эту архитектуру. - person Kitalda; 24.02.2016
comment
На самом деле я расширил класс Application и сохранил там свою модель данных. В намерениях я только передал ID объектов данных, которые можно использовать для извлечения исходного объекта из класса Application. Также расширенный класс приложения уведомляет все объекты, использующие модель данных, если она изменяется с помощью стандартной концепции слушателя. Я знаю, что это подходит только для моего случая, когда мне нужно поделиться моделью данных для всего приложения, но в этом случае это идеально, и статические классы и поля также не нужны! - person Markus; 24.02.2016

Безусловно, самый простой способ ИМХО для посылки объектов. Вы просто добавляете аннотационный тег над объектом, который хотите разделить.

Пример из библиотеки ниже 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; }
}
person Community    schedule 07.10.2015

Сначала внедрите Parcelable в свой класс. Затем передайте такой объект.

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

Строка пакета не обязательна, просто строка должна быть одинаковой в обоих действиях.

СПРАВОЧНИК

person Community    schedule 19.11.2016

Начать другое действие из этого действия передать параметры через объект Bundle

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

Получить информацию о другом действии (YourActivity)

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

Это нормально для простого типа данных. Но если вы хотите передавать сложные данные между действиями, вам нужно сначала сериализовать их.

Здесь у нас есть модель сотрудника

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

    getters...
    setters...
}

Вы можете использовать Gson lib, предоставленную Google, для сериализации таких сложных данных, как это

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);
person Community    schedule 23.06.2017

Самый простой и java-способ сделать: реализовать сериализуемый в вашем классе pojo / model

Рекомендуется для Android для просмотра производительности: сделайте модель доступной для отправки

person Community    schedule 03.07.2019

Если вы не особо разбираетесь в использовании функции putExtra и просто хотите запустить другое действие с объектами, вы можете проверить GNLauncher (https://github.com/noxiouswinter/gnlib_android/wiki#gnlauncher), я написал в попытке упростить этот процесс.

GNLauncher делает отправку объектов / данных в Activity из другого Activity так же просто, как вызов функции в Activity с необходимыми данными в качестве параметров. Он вводит безопасность типов и устраняет все проблемы, связанные с сериализацией, присоединением к намерению с помощью строковых ключей и отменой того же самого на другом конце.

person Community    schedule 02.11.2014

Самым простым было бы просто использовать следующее, где элемент является строкой:

intent.putextra("selected_item",item)

Для получения:

String name = data.getStringExtra("selected_item");
person Community    schedule 24.06.2010
comment
это только для строки, целого числа и т.д., но я хочу, чтобы объект и использование статического объекта было только возможным. - person UMAR-MOBITSOLUTIONS; 25.06.2010

POJO класс "Сообщение" (обратите внимание, что он реализован как Serializable)

package com.example.booklib;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import android.graphics.Bitmap;

public class Post implements Serializable{
    public String message;
    public String bitmap;
    List<Comment> commentList = new ArrayList<Comment>();
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getBitmap() {
        return bitmap;
    }
    public void setBitmap(String bitmap) {
        this.bitmap = bitmap;
    }
    public List<Comment> getCommentList() {
        return commentList;
    }
    public void setCommentList(List<Comment> commentList) {
        this.commentList = commentList;
    }

}

Класс POJO "Комментарий" (поскольку он является членом класса Post, он также необходим для реализации Serializable)

    package com.example.booklib;

    import java.io.Serializable;

    public class Comment implements Serializable{
        public String message;
        public String fromName;
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public String getFromName() {
            return fromName;
        }
        public void setFromName(String fromName) {
            this.fromName = fromName;
        }

    }

Затем в своем классе действий вы можете сделать следующее, чтобы передать объект другому действию.

ListView listview = (ListView) findViewById(R.id.post_list);
listview.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            Post item = (Post)parent.getItemAtPosition(position);
            Intent intent = new Intent(MainActivity.this,CommentsActivity.class);
            intent.putExtra("post",item);
            startActivity(intent);

        }
    });

В вашем классе получателя "CommentsActivity" вы можете получить следующие данные

Post post =(Post)getIntent().getSerializableExtra("post");
person Community    schedule 21.10.2016

Я знаю, что это немного поздно, но если вы хотите сделать это только для нескольких объектов, почему бы вам просто не объявить свои объекты как общедоступные статические объекты в своей целевой деятельности?

public static myObject = new myObject();

а из вашей исходной активности просто дать ему значение?

destinationActivity.myObject = this.myObject;

в исходной активности вы можете использовать его как любой глобальный объект. Для большого количества объектов это может вызвать некоторые проблемы с памятью, но для небольшого количества объектов я думаю, что это лучший способ сделать

person Community    schedule 01.12.2014
comment
Если сделать статическим любой объект, он будет отмечен как активный. JVM и DVM пропустят очистку этого ресурса во время завершения (алгоритм Mark and Weep). Поэтому вам нужно обнулить этот объект вручную для управления памятью. КОРОТКО НЕ ХОРОШИЙ ПОДХОД - person Gaganpreet Singh; 15.01.2015
comment
Я ясно сказал, что этот подход может вызвать некоторые проблемы с памятью .... но для одного или двух объектов вы можете вручную присвоить ему значение null, не имеет большого значения! - person Mothana; 15.01.2015
comment
Вы можете использовать, если вас устраивает это ограничение создания статического объекта. - person Gaganpreet Singh; 15.01.2015

person    schedule
comment
Пожалуйста, попробуйте, это сработает для меня .. Вот Модель - это притча. - person Alok Singh; 20.12.2018