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

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

код для класса Customer:

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.

как я могу этого достичь?

30 ответов


один из вариантов может позволить вашему пользовательскому классу реализовать Serializable интерфейс, а затем вы можете передать экземпляры объектов в intent extra, используя putExtra(Serializable..) вариант Intent#putExtra() метод.

псевдокод:

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

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

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

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

реализуйте свой класс с помощью Serializable. Предположим, что это ваш класс сущности:

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

мы отправляем объект под названием dene от активности X к активности Y. Где-то в X активности;

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

в y деятельности мы получаем объект.

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

вот и все.


  • использование global статические переменные не являются хорошей программной инженерией практика.
  • преобразование полей объекта в примитивные типы данных могут быть лихорадочная работа.
  • С помощью сериализуемый в порядке, но он не эффективен для производительности на платформе Android.
  • Parcelable специально предназначен для Android, и вы должны использовать его. Вот простой пример: передача пользовательских объектов между действиями Android

вы можете создать Parcelable код для вас класса, используя это сайт.


при вызове activity

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

В toClass.java получает действие по

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

пожалуйста, убедитесь, что класс customer реализует parcelable

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

по моему опыту есть три основных решения, каждое со своими недостатками и преимуществами:

  1. Реализует Parcelable

  2. Реализация Serializable

  3. используя облегченную библиотеку шины события некоторого вида (например, EventBus Greenrobot или Otto квадрата)

Parcelable - быстрый и стандарт Андроида, но он имеет серии шаблонный код и требует жестко закодированных строк для ссылки при извлечении значений из намерения (не сильно типизированных).

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

Автобусная Событие - zero boilerplate, самый быстрый подход, и не требует трудн-закодированных строк, но он делает требуется дополнительная зависимость (хотя обычно легкая, ~40 КБ)

Я опубликовал очень подробное сравнение вокруг этих трех подходов, включая критерии эффективности.


использовать gson чтобы преобразовать ваш объект в JSON и передать его через intent. В новом действии преобразуйте JSON в объект.

в своем build.gradle, добавьте это в свои зависимости

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

в вашей деятельности преобразуйте объект в JSON-string:

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

в вашей активности приема преобразуйте JSON-строку обратно в исходный объект:

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

на Котлин это то же самое

пропуск данные

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

получаем

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

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

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

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

вы также можете передать их непосредственно вместо temp Иварс, но так, по-моему, яснее. Кроме того, вы можете установить temp ivars в null, чтобы они быстрее очищались GarbageCollector.

удачи!

на боковом примечании: переопределите toString () вместо написания собственного метода печати.

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

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

я нашел простой и элегантный способ:

  • нет Parcelable
  • не сериализуемый
  • нет статического поля
  • Не Автобус

Способ 1

код для первого действия:

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

код для второго действия:

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

вы найдете objSent & objReceived же hashCode, так они идентичны.

но почему мы можем передать объект java таким образом?

на самом деле, Android binder создаст глобальную ссылку JNI для объекта java и выпустит эту глобальную ссылку JNI, когда нет ссылки для этого объекта java. binder сохранит эту глобальную ссылку JNI в объекте Binder.

*внимание: этот метод работает только, если два действия выполняются в одном процессе, в противном случае бросьте ClassCastException на (ObjectWrapperForBinder) getIntent ().getExtras().getBinder ("object_value")*

класс ObjectWrapperForBinder defination

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Способ 2

  • для отправителя,
    1. используйте пользовательский собственный метод для добавления объекта java в глобальную справочную таблицу JNI (через JNIEnv::NewGlobalRef)
    2. поместите возвращаемое целое число (на самом деле, jnienv::NewGlobalRef возвращает jobject, который является указателем, мы можем привести его к int безопасно), чтобы ваше намерение (через Intent::putExtra)
  • для приемника
    1. получить целое число от Intent (через Intent::getInt)
    2. используйте пользовательский собственный метод для восстановления объекта java из глобальной справочной таблицы JNI (через JNIEnv::NewLocalRef)
    3. удалить элемент из глобальной справочной таблицы JNI(через JNIEnv:: DeleteGlobalRef),

но Метод 2 имеет небольшую, но серьезную проблему, если приемник не работает чтобы восстановить объект java (например, какое-то исключение происходит перед восстановлением объекта java или действие receiver вообще не существует), объект java станет сиротой или утечкой памяти, Метод 1 не имеет этой проблемы, потому что Android binder будет обрабатывать это исключение

Способ 3

чтобы вызвать объект java удаленно, мы создадим контракт данных / интерфейс для описания объекта java, мы будем использовать aidl файл

IDataContract.AIDL по

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

код для первого действия

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

код для второго действия:

измените атрибут android: process в AndroidManifest.xml к непустому имени процесса, чтобы убедиться, что второе действие выполняется в другом процессе

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

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

метод 4

метод 3 кажется недостаточно простым, потому что мы должны реализовать интерфейс aidl. Если вы просто хотите выполнить простую задачу, а возвращаемое значение метода не нужно, мы можем использовать android.ОС.Посланник!--13-->

код для первого действия (отправителя):

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

код для второго действия (приемника):

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

    }
}

все Посланник.отправка будет выполняться в обработчике асинхронно и последовательно.

на самом деле, android.ОС.Messenger также является интерфейсом aidl, если у вас есть исходный код android, вы можете найти файл с именем IMessenger.AIDL по

package android.os;

import android.os.Message;

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

Я сделал синглтон вспомогательный класс, который содержит временные объекты.

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

вместо того, чтобы помещать свои объекты в Intent, используйте IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

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

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

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


существует несколько способов доступа к переменным или объектам в других классах или действиях.

Базы Данных А.

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

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

D. класс, который может содержать общие данные, можно назвать общими утилитами. Это зависит от тебя.

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

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

А. база данных

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

уроки

Б. общие параметры

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

Как хранить

 // Create object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

 //Now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();

 //Put your value
 editor.putString("userName", "stackoverlow");

 //Commits your edits
 editor.commit();

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

Как выбрать

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

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

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

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

используйте Java beans и храните в нем как одно из его полей и используйте геттеры и сеттеры для этого.

JavaBeans классы Java, которые имеют свойства. Думать о свойства как переменные частного экземпляра. Так как они частные, единственный способ к ним можно получить доступ извне их класса через методы в классе. Вызываются методы, изменяющие значение свойства методы setter и методы, которые извлекают значение свойства, называются методами getter.

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

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

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

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

если вы хотите учебник для этого перейдите на страницу:

Д. CommonUtilities

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

пример

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

Е. передача данных через intents

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


лучший способ-иметь класс (назовите его Control) в вашем приложении, который будет содержать статическую переменную типа "клиент" (в вашем случае). Инициализировать переменную в вашей деятельности А.

например:

Control.Customer = CustomerClass;

затем перейдите к действию B и извлеките его из класса Control. Не забудьте назначить null после использования переменной, иначе память будет потрачена впустую.


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

Теперь вы хотите передать объект этого класса в startActivity. Просто используйте это:

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

это работает здесь, потому что MyClass реализует Serializable.


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

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

}

в своем onCreate() метод

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

на xyz activity class вам нужно использовать следующий код:

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

если вы выберете использовать способ Samuh описывает, помните, что только примитивные значения могут быть отправлены. То есть, ценности, которые parcable. Таким образом, если ваш объект содержит сложные объекты, они не будут следовать. Например, переменные, такие как Bitmap, HashMap и т. д... Их сложно обойти вниманием.

В общем, я бы посоветовал вам отправлять только примитивные типы данных в качестве дополнительных, таких как String, int, boolean и т. д. В вашем случае это было бы:String fname, String lname, int age, и String address.

мое мнение: более сложные объекты лучше разделить, реализовав ContentProvider, SDCard, etc. Также можно использовать статическая переменная, но это может быстро привести к ошибкам кода...

но опять же, это только мое субъективное мнение.


Я использую parcelable для отправки данных из одного действия в другое acivity. Вот мой код, который отлично работает в моем проекте.

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

в activityA используйте его так:

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

в ActivityB используйте его так, чтобы получить данные:

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

Вы можете попробовать использовать этот класс. Ограничение заключается в том, что его нельзя использовать вне одного процесса.

одно действие:

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

другое упражнение:

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

Crete класс, как класс bean и реализовать Serializable интерфейс. Тогда мы сможем пройти через intent способ, например:

intent.putExtra("class", BeanClass);

затем получить его от другой деятельности, например:

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

создайте два метода в своем пользовательском классе, как это

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

Теперь в вашей деятельности отправителя сделайте так

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

и в вашей активности приемника

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

запустите другое действие из этого действия и передайте параметры через Bundle Object

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

Retrive данные о другой деятельности (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);

этот вопрос также обсуждается в другом вопросе переполнения стека. Пожалуйста, посмотрите на решение передача данных через intent с помощью Serializable. Главное - использовать Bundle объект, который хранит необходимые данные внутри Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

для извлечения значений:

 Bundle bundle = new Bundle();

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

преимущество Serializable является его простота. Тем не менее, вы должны рассмотреть возможность использования Parcelable метод, если вам нужно много данных перевели, потому что Parcelable специально разработан для Android, и он более эффективен, чем Serializable. Вы можете создать Parcelable класс через:

  1. онлайн-инструмент - parcelabler
  2. плагин для Android Studio -генератор кода Android Parcelable

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


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

оригинальный вопрос задан "как передать объект из одного действия в другое в Android", и никто не ответил на это. Конечно, вы можете сериализовать (сериализуемый, Parcelable, to/from JSON) и передать копию данных объекта, и новый объект, имеющий те же данные, может быть создан; но он не будет иметь те же ссылки/дескрипторы. Кроме того, многие другие упоминали, что вы можете хранить ссылку в статическом хранилище. И это будет работать, если Android не решит onDestroy ваш Деятельность.

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

Для справки:

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

onDestroy "система временно уничтожение этого экземпляра деятельности для сохранения космоса."

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

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


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

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

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

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


выше ответы почти все правильные, но для тех, кто не поймете ответы Android имеет мощный класс намерение С его помощью Вы делитесь данными между не только деятельностью, но и другими компонентами Android (broadcasr receiver, servises for content обеспечивают использование класса ContetnResolver без намерения). В своей деятельности вы строите intent

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

в вашей receving деятельности у вас есть

public class SomeActivity extends AppCompactActivity {

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

}

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


Я всегда задавался вопросом, почему это не может быть так просто, как вызов метода другой деятельности. Недавно я написал служебную библиотеку, которая делает ее почти такой же простой. Вы можете проверить это здесь(https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).

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

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

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

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

реализуйте вышеуказанный интерфейс для запуска активности. Также сообщим GNLauncher когда работа готова.

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

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

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

будет запущено первое действие и вызван метод с требуемыми параметрами.

предпосылки

пожалуйста, обратитесь к https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites для получения информации о том, как добавить зависимости.


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

(1) источник активности

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

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

(2) acitivity назначения

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

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

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

Android DataCache


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

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

передать одно действие другому:

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

получаем значения:

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

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

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

создание связующего достаточно просто...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

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

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

    };
}

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

Я бы посоветовал проверить наличие нулей, и если instanceof 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();

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