Как передать объект из одного действия в другое на Android
Я пытаюсь выполнить отправку объекта моего класса клиента с одного 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
.
Как я могу это достичь?
Ответы
Ответ 1
Один из вариантов может позволить вашему пользовательскому классу реализовать интерфейс Serializable
, а затем вы можете передать экземпляры объекта в намерении дополнительно, используя вариант putExtra(Serializable..)
метода Intent#putExtra()
.
псевдокод
//To pass:
intent.putExtra("MyClass", obj);
// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Ответ 2
Внедрите свой класс с помощью 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");
Что это.
Ответ 3
- Использование глобальных статических переменных не является хорошей практикой разработки программного обеспечения.
- Преобразование полей объекта в примитивные типы данных может быть тяжелой работой.
- Использование сериализуемого кода в порядке, но оно неэффективно на платформе Android.
- Parcelable специально предназначен для Android, и вы должны его использовать. Вот простой пример: Передача пользовательских объектов между действиями Android
Вы можете создать Parcelable code для своего класса, используя этот сайт.
Ответ 4
При вызове операции
Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);
В toClass.java получить активность
Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");
Пожалуйста, убедитесь, что класс клиента реализует достоверные
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();
}
Ответ 5
По моему опыту есть три основных решения, каждый из которых имеет свои недостатки и преимущества:
Parcelable - быстрый и Android-стандарт, но он имеет множество шаблонов и требует жестко закодированных строк для ссылки при вытягивании значений из намерения (не строго типизированный).
Сериализуемый - близок к нулевому шаблону, но это самый медленный подход, а также требует жестко закодированных строк при вытягивании значений из намерения (не строго типизированный).
Шина событий - нулевой шаблон, самый быстрый подход и не требует жестко закодированных строк, но для этого требуется дополнительная зависимость (хотя обычно это легкий, ~ 40 KB)
Я опубликовал очень подробное сравнение этих трех подходов, включая контрольные показатели эффективности. Если вас это интересует, вы можете найти его на
Передача объектов между действиями Android.
Ответ 6
Используйте gson, чтобы преобразовать свой объект в JSON и передать его с помощью намерения. В новой Деятельности преобразуйте JSON в объект.
Пример:
Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);
И в следующем упражнении, где вы хотите передать объект:
Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);
Ответ 7
Вы также можете записать данные объекта во временные строки и 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 ivars, но таким образом это яснее, на мой взгляд. Кроме того, вы можете установить временные ивары temp равными нулю, чтобы скорее очистить GarbageCollector.
Удачи!
На стороне примечание: переопределите toString() вместо написания собственного метода печати.
Как уже упоминалось в комментариях ниже, так вы возвращаете свои данные в другой активности:
String fName = getIntent().getExtras().getInt("fname");
Ответ 8
Я нашел простой и элегантный метод:
- НЕТ ПОСЛЕДНИЕ
- НЕТ Serializable
- НЕТ статического поля
- Нет шины событий
Метод 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 создаст глобальную ссылку JNI для Java-объекта и опубликует эту глобальную ссылку JNI, если для этого java-объекта нет ссылки. связующее сохраняет эту глобальную ссылку JNI в объекте Binder.
* ПРЕДОСТЕРЕЖЕНИЕ: этот метод ТОЛЬКО работает, если два действия не выполняются в одном и том же процессе, иначе бросают ClassCastException в (ObjectWrapperForBinder) getIntent(). getExtras(). getBinder ( "object_value" ) *
class ObjectWrapperForBinder defining
public class ObjectWrapperForBinder extends Binder {
private final Object mData;
public ObjectWrapperForBinder(Object data) {
mData = data;
}
public Object getData() {
return mData;
}
}
Метод 2
- для отправителя,
- используйте собственный собственный метод для добавления объекта Java в глобальную ссылочную таблицу JNI (через JNIEnv:: NewGlobalRef).
- поместите возвращаемое целое число (на самом деле, JNIEnv:: NewGlobalRef возвращает jobject, который является указателем, мы можем безопасно использовать его для int) для вашего намерения (через Intent:: putExtra)
- для приемника
- получить целое число от Intent (через Intent:: getInt)
- использовать собственный собственный метод для восстановления объекта java из глобальной справочной таблицы JNI (через JNIEnv:: NewLocalRef)
- удалить элемент из глобальной справочной таблицы JNI (через
JNIEnv:: DeleteGlobalRef),
Но метод 2 имеет небольшую, но серьезную проблему, если получателю не удается восстановить объект java (например, какое-то исключение происходит до восстановления java-объекта или активность получателя вообще отсутствует), тогда объект java станет сиротой или утечкой памяти,
Метод 1 не имеет этой проблемы, потому что привязка для android будет обрабатывать это исключение
Способ 3
Чтобы вызвать объект java удаленно, мы создадим контракт/интерфейс данных для описания объекта java, мы будем использовать файл helpl
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 выглядит не достаточно простым, потому что мы должны реализовать интерфейс helpl.
Если вы просто хотите выполнить простую задачу, а возвращаемое значение метода не нужно, мы можем использовать android.os.Messenger
Код для первого действия (отправителя):
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();
}
}
}
Все Messenger.send будет выполняться в обработчике асинхронно и последовательно.
Собственно, android.os.Messenger также является вспомогательным интерфейсом, если у вас есть исходный код Android, вы можете найти файл с именем IMessenger.aidl
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
Ответ 9
Я создал один вспомогательный класс, содержащий временные объекты.
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");
Помните, что после загрузки объект удаляется, чтобы избежать ненужных ссылок.
Ответ 10
Существует несколько способов доступа к переменным или объектам в других классах или Activity.
а. База данных
В. Общие предпочтения.
С. Сериализация объектов.
Д. Класс, который может содержать общие данные, можно назвать Common Utilities. Это зависит от вас.
Е. Передача данных через Intents и Parcelable Interface.
Это зависит от ваших потребностей проекта.
а. База данных
SQLite - это база данных с открытым исходным кодом, встроенная в Android. SQLite поддерживает стандартные функции реляционных баз данных, такие как синтаксис SQL, транзакции и подготовленные операторы.
Учебники
В. Общие настройки
Предположим, вы хотите сохранить имя пользователя. Итак, теперь будет две вещи: ключевое имя пользователя, значение.
Как сохранить
// 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);
Затем используйте сериализацию объектов для сериализации этого объекта, а в другом классе десериализуйте этот объект.
В сериализации объект может быть представлен как последовательность байтов, которая включает данные объекта, а также информацию о типе объекта и типах данных, хранящихся в объекте.
После того, как сериализованный объект был записан в файл, он может быть прочитан из файла и десериализован. То есть информация о типе и байты, которые представляют объект и его данные, могут использоваться для воссоздания объекта в памяти.
Если вы хотите, чтобы учебник для этого ссылался на:
Д. CommonUtilities
Вы можете создать класс самостоятельно, который может содержать общие данные, которые вам часто нужны в вашем проекте.
Пример
public class CommonUtilities {
public static String className = "CommonUtilities";
}
Е. Передача данных через намерения
Пожалуйста, обратитесь к учебнику Android - данные посылки для передачи между действиями с использованием классов Parcelable для этой опции передачи данных.
Ответ 11
Лучший способ - иметь класс (назовите его "Управление" ) в своем приложении, в котором будет храниться статическая переменная типа "Клиент" (в вашем случае). Инициализируйте переменную в своей активности A.
Например:
Control.Customer = CustomerClass;
Затем перейдите в Activity B и выберите его из класса Control. Не забудьте присвоить значение null после использования переменной, иначе память будет потрачена впустую.
Ответ 12
public class MyClass implements Serializable{
Here is your instance variable
}
Теперь вы хотите передать объект этого класса в startActivity. Просто используйте это:
Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);
Это работает здесь, потому что MyClass реализует Serializable
.
Ответ 13
Создайте свой собственный класс 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;
}
}
В вашем методе onCrate()
@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
вы можете использовать следующий код:
Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
Ответ 14
Если вы решите использовать способ, которым описывает Самух, помните, что могут быть отправлены только примитивные значения. То есть значения, которые являются разделяемыми. Итак, если ваш объект содержит сложные объекты, это не будет следовать. Например, такие переменные, как Bitmap, HashMap и т.д. Это сложно сделать по намерениям.
В общем, я бы посоветовал вам отправлять только примитивные типы данных как дополнительные, такие как String, int, boolean и т.д. В вашем случае это будут: String fname
, String lname
, int age
и String address
.
Мое мнение: более сложные объекты лучше разделяют, реализуя ContentProvider, SDCard и т.д. Также возможно использовать статическую переменную , но это может быстро привести к подверженному ошибкам коду...
Но опять же, это просто мое субъективное мнение.
Ответ 15
Я использую возможность для передачи данных из одной активности в другую. Вот мой код, который отлично работает в моем проекте.
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");
Ответ 16
Вы можете попробовать использовать этот класс. Ограничение заключается в том, что он не может использоваться вне одного процесса.
Одно действие:
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);
}
}
Ответ 17
Создайте класс класса bean и реализуйте интерфейс Serializable
. Затем мы можем передать его через метод intent
, например:
intent.putExtra("class", BeanClass);
Затем получите его из другого действия, например:
BeanClass cb = intent.getSerializableExtra("class");
Ответ 18
Этот вопрос также обсуждается в другом вопросе. Посмотрите решение для передачи данных с помощью 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
, используя:
Ответ 19
Создайте два метода в своем пользовательском классе, например
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"));
Ответ 20
Запустите еще одно действие из этого действия и передайте параметры через объект Bundle
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "[email protected]");
startActivity(intent);
Извлечь данные о другой активности (YourActivity)
String s = getIntent().getStringExtra("USER_NAME");
Это нормально для простого типа данных.
Но если вы хотите передать сложные данные между действиями. U необходимо сначала выполнить сериализацию.
Здесь у нас есть модель сотрудника
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);
Ответ 21
Да, использование статического объекта - самый простой способ сделать это с помощью пользовательских несериализуемых объектов.
Ответ 22
Объекты активности Android могут быть уничтожены и восстановлены. Таким образом, вам нужно будет использовать другой подход, чтобы посмотреть их - или любой объект, который они создают!!! - вверх. То есть вы могли бы пройти как статическую ссылку на класс, но затем дескриптор объекта (Java вызывает эти "ссылки", как и SmallTalk, но они не являются ссылками в смысле C или сборки), возможно, позже будет недействительным, поскольку "функция", Android OE - любая деятельность может быть уничтожена и восстановлена позже.
В оригинальном вопросе "Как передать объект из одной активности в другую в Android", и никто не ответил на это. Разумеется, вы можете сериализовать (Serializable, Parcelable, to/from JSON) и передать копию данных объекта и создать новый объект с теми же данными; но у него НЕ будут одинаковые ссылки/ручки. Кроме того, многие другие упомянули, что вы можете сохранить ссылку в статическом хранилище. И это будет работать, если Android не решит onDestroy вашей деятельности.
Итак, чтобы действительно решить исходный вопрос, вам понадобится статический поиск, и каждый объект будет обновлять свою ссылку, когда/если она будет воссоздана. Например. каждая активность Android будет самореализоваться, если вызывается ее onCreate. Вы также можете увидеть, как некоторые люди используют список задач для поиска активности по имени. (система временно уничтожает этот экземпляр активности для сохранения space..getRunningTasks, список задач является фактически специализированным списком самого последнего экземпляра объекта для каждого действия).
Для справки:
Остановился: "Активность полностью затенена другой деятельностью (активность теперь находится в" фоновом режиме "). Также приостановлена активность (объект Объект активности сохраняется в памяти, он поддерживает все состояние и член но не прикреплен к диспетчеру окон). Однако он больше не виден пользователю и может быть убит системой, если в другом месте требуется память".
OnDestroy "система временно уничтожает этот экземпляр для экономии места".
Таким образом, шина сообщений является работоспособным решением. Это в основном "пьет". Вместо того, чтобы пытаться иметь ссылки на объекты; то вы перепроектируете свой дизайн, чтобы использовать MessagePassing вместо SequentialCode. Экспоненциально сложнее отлаживать; но это позволяет вам игнорировать такое понимание OperatingEnvironment. Эффективно каждый доступ к объектным методам инвертируется, поэтому вызывающий объект отправляет сообщение, а сам объект определяет обработчик для этого сообщения. Больше кода, но может сделать его надежным с ограничениями Android OE.
Если все, что вам нужно, - это самая активная деятельность (типичная вещь в приложениях Android из-за необходимости "Контекста" ), тогда вы можете просто иметь каждый список активности как "топ" в статическом глобальном пространстве всякий раз, когда вызывается его onResume, Тогда ваш AlertDialog или что-то, что нуждается в контексте, может просто захватить его оттуда. Кроме того, его немного yucky, чтобы использовать глобальный, но может упростить передачу контекста вверх и вниз повсюду и, конечно же, когда вы используете MessageBus, тогда это глобально.
Ответ 23
-
Я знаю, что статический вред, но кажется, что мы вынуждены использовать его здесь. Проблема с 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()
-
Другой способ - объявить статическое поле класса, которое вы хотите передать в этом самом классе. Он будет служить только для этой цели. Не забывайте, что он может быть пустым в onCreate, потому что ваш пакет приложений был выгружен из памяти системой и перезагружен позже.
-
Принимая во внимание, что вам все еще нужно обрабатывать жизненный цикл деятельности, вы можете записать все данные прямо на общие настройки, болезненно со сложными структурами данных, как есть.
Ответ 24
Я всегда задавался вопросом, почему это не может быть так просто, как вызвать метод другого действия. Недавно я написал библиотеку утилиты, которая делает ее почти такой же простой. Вы можете проверить это здесь (https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).
GNLauncher делает отправку объектов/данных в Activity из другого Activity и так проще, как вызов функции в Activity с требуемыми данными в качестве параметров. Он вводит безопасность типов и удаляет все препятствия, связанные с сериализацией, присоединением к намерению с использованием строковых клавиш и отменой их на другом конце.
Использование
Определите интерфейс с методами, которые вы хотите вызвать при запуске Activity.
public interface IPayload {
public void sayHello(String name, int age);
}
Внедрите описанный выше интерфейс в Activity для запуска.
Также уведомляйте 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);
}
}
В другой Activity, получите прокси-сервер для вышеупомянутого Действия и вызовите любой метод с желаемыми параметрами.
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.
Ответ 25
Передать объект из одной активности в другую.
(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");
Ответ 26
Я использовал для установки объекта с Pacelable или Serializable для передачи, но всякий раз, когда я добавляю другие переменные в объект (модель), мне приходится регистрировать все это. Это так неудобно.
Это очень легко передать объект между действиями или фрагментами.
Android DataCache
Ответ 27
Мы можем передать объект из одной активности в другую:
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");
Ответ 28
Выше ответы почти все правильны, но для тех, кто не отвечает на эти ответы
Android обладает мощным классом Intent, благодаря которому вы обмениваетесь данными между не только активностью, но и другими компонентами Android (широкоэкранный приемник, сервисы для контента, мы используем ContetnResolver class no Intent).
В вашей деятельности вы строите намерение
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, а не Serializable интерфейс на объекте, который специально для этого имеет плагин. Загрузите его и используйте
Ответ 29
Передайте одно действие другому:
startActivity(new Intent(getBaseContext(),GetActivity.class).putExtra("passingkey","passingvalue"));
Получить значения:
String myvalue= getIntent().getExtras("passingkey");
Ответ 30
Привет всем, я вижу много хороших вариантов, но мне было интересно, почему 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();
Если кто-то может сойти с ума и сделать этот сосун истинным родовым.