Как передать объект из одного действия в другое на Android - PullRequest
696 голосов
/ 29 апреля 2010

Я пытаюсь отправить объект моего клиента класса из одного Activity и отобразить его в другом Activity.

Код для класса клиента:

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

Я хочу отправить свой объект с одного Activity на другой, а затем отобразить данные на другом Activity.

Как мне этого добиться?

Ответы [ 31 ]

3 голосов
/ 14 мая 2011

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

3 голосов
/ 05 сентября 2014

Android-объекты деятельности могут быть уничтожены и восстановлены. Таким образом, вам нужно будет использовать другой подход для поиска их - или любого объекта, который они создают !!! - вверх То есть вы можете передать как ссылку на статический класс, но тогда дескриптор объекта (Java вызывает эти «ссылки», как и SmallTalk; но они не являются ссылками в смысле C или сборки), возможно, будет позже недействительным, потому что «функция» Android OE - это любая Деятельность, которую можно уничтожить и восстановить позже.

Первоначальный вопрос: «Как передать объект из одного действия в другое в Android», и никто не ответил на это. Конечно, вы можете сериализовать (Serializable, Parcelable, в / из JSON) и передать копию данных объекта, и новый объект, имеющий те же данные, может быть создан; но он НЕ будет иметь одинаковые ссылки / дескрипторы. Также многие другие упоминали, что вы можете хранить ссылку в статическом хранилище. И это будет работать, если Android не решит удалить вашу активность.

Итак, чтобы действительно решить исходный вопрос, вам понадобится статический поиск, и каждый объект обновит свою ссылку, когда / если он будет создан заново. Например. каждое действие Android будет самоотверженным, если вызывается его onCreate. Вы также можете увидеть, как некоторые люди используют список задач для поиска действия по имени. (система временно уничтожает этот экземпляр действия, чтобы сэкономить место. getRunningTasks, список задач - это фактически специализированный список самого последнего экземпляра объекта каждого действия).

Для справки:

Остановлено: «Действие полностью скрыто другим действием (действие теперь находится в« фоне »). Остановленное действие также все еще живо ( Объект действия сохраняется в памяти , он сохраняет всю информацию о состоянии и членах). , но не прикреплен к диспетчеру окон.) Однако он больше не виден пользователю и может быть уничтожен системой, когда требуется память в другом месте. "

OnDestroy «Система временно уничтожает этот экземпляр действия для экономии места.»

Итак, шина сообщений является работоспособным решением. Это в основном "каламбуры". Вместо того, чтобы пытаться иметь ссылки на объекты; затем вы перепроектируете свой дизайн, чтобы использовать MessagePassing вместо SequentialCode. Экспоненциально сложнее отлаживать; но это позволяет вам игнорировать такого рода понимание операционной среды. Фактически, каждый метод доступа к объекту инвертируется, поэтому вызывающая сторона публикует сообщение, а сам объект определяет обработчик для этого сообщения. Много кода, но он может быть устойчивым с ограничениями Android OE.

Если все, что вам нужно, это верхняя активность (типичная вещь в приложениях для Android из-за повсеместного «контекста»), тогда вы можете просто указывать каждую активность как «верхнюю» в статическом глобальном пространстве всякий раз, когда вызывается его onResume , Тогда ваш AlertDialog или любой другой, которому нужен контекст, может просто взять его оттуда. Кроме того, немного неприятно использовать глобальный код, но он может упростить передачу контекста вверх и вниз повсюду, и, конечно, когда вы используете MessageBus, тогда он в любом случае глобален.

2 голосов
/ 03 мая 2013
  1. Я знаю, что статика плохая, но, похоже, мы вынуждены использовать ее здесь. Проблема с parceables / seriazables заключается в том, что в двух действиях есть повторяющиеся экземпляры одного и того же объекта = потеря памяти и процессора.

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

Активность вызова

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

Вызываемое действие (обратите внимание, что onCreate () и onResume () могут вызываться несколько раз, когда система уничтожает и воссоздает действия)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Другой способ - объявить статическое поле класса, который вы хотите передать в этом самом классе. Это будет служить только для этой цели. Не забывайте, что он может быть нулевым в onCreate, потому что ваш пакет приложения был выгружен из памяти системой и перезагружен позже.

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

1 голос
/ 14 марта 2017

Над ответами почти все правильно, но для тех, кто не понимает эти ответы У Android есть мощный класс Intent , с помощью которого вы обмениваетесь данными не только с действиями, но и с другими компонентами Android (приемник вещания, услуги для контента, если мы используем класс ContetnResolver без намерения). В своей деятельности вы строите намерение

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

В вашей принимающей деятельности у вас есть

public class SomeActivity extends AppCompactActivity {

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

}

Вы должны реализовать интерфейс Parceable или Serializable на вашем объекте, чтобы разделить действия. Трудно реализовать Parcealbe , а не Сериализуемый интерфейс на объекте, поэтому Android имеет плагин специально для этого. Загрузите его и используйте его

0 голосов
/ 17 сентября 2011

Как упоминалось в комментариях, этот ответ нарушает инкапсуляцию и тесно связывает компоненты, что, скорее всего, не то, что вам нужно. Лучшее решение, вероятно, - сделать ваш объект Parcelable или Serializable, как объясняют другие ответы. Сказав это, решение решает проблему. Итак, если вы знаете, что делаете:

Использовать класс со статическими полями:

public class Globals {
    public static Customer customer = new Customer();
}

Внутри деятельности вы можете использовать:

Активность от:

Globals.customer = myCustomerFromActivity;

Цель деятельности:

myCustomerTo = Globals.customer;

Это простой способ передачи информации для действий.

0 голосов
/ 29 мая 2017

Передача одного занятия другому:

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

Получить значения:

String myvalue= getIntent().getExtras("passingkey");
0 голосов
/ 13 июля 2016

Привет всем. Я вижу много хороших вариантов, но мне было интересно, почему Binding не использовался?

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

Создать подшивку достаточно просто ...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

И создание пакета для его использования не так уж плох, эфир.

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

    };
}

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

Я бы посоветовал проверять наличие нулей, а если экземпляр Binder - MyBinder!

и для реализации этого вы просто ...

Отправить его

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

intent.putExtra("MyParcelable", myParcelable);

Верни его

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

Черт возьми, кто-то может сойти с ума и сделать эту присоску настоящим родовым.

0 голосов
/ 18 ноября 2015

Мы можем передать объект из одного действия в другое:

SupplierDetails poSuppliersDetails = new SupplierDetails();

Внутри poSuppliersDetails у нас есть некоторые значения. Сейчас я отправляю этот объект целевой активности:

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

Как получить это в ACtivityTwo:

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");
0 голосов
/ 04 октября 2015

Я использовал для установки объекта с помощью Pacelable или Serializable для передачи, но всякий раз, когда я добавляю другие переменные в объект (модель), я должен регистрировать все это. Это так неудобно.

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

Android DataCache

0 голосов
/ 13 июля 2015

Передача объекта из одного занятия в другое.

(1) исходная деятельность

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

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

(2) целевая активность

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