android — Как отправить объекты через связку" />

Как отправить объекты через связку

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

Проблема в том, что он не имеет ничего общего с намерениями или контекстами и имеет большое количество непримитивных объектов. Как мне упаковать класс в пакетный /сериализуемый и передать его в startActivityForResult?

108 голосов | спросил ahodder 22 12010vEurope/Moscow11bEurope/MoscowMon, 22 Nov 2010 23:25:14 +0300 2010, 23:25:14

11 ответов


0

Чтобы понять, какой путь выбрать, необходимо ответить не только на ключевой вопрос CommonsWare «почему», но и на вопрос «к чему?» Вы передаете это.

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

1) Вы можете разбить объект на составляющие его данные, и если объект на другом конце знает об объекте того же типа, он может собрать клон из сериализованных данных. Вот так большинство распространенных типов проходят через связки.

2) Вы можете передать непрозрачную ручку. Если вы передаете его в том же контексте (хотя можно спросить, зачем это нужно), это будет дескриптор, который вы можете вызвать или разыменовать. Но если вы передадите его через Binder в другой контекст, его буквальное значение будет произвольным числом (на самом деле, эти произвольные числа отсчитываются последовательно от запуска). Вы ничего не можете сделать, кроме как отслеживать это, пока не передадите его обратно в исходный контекст, что заставит Binder преобразовать его обратно в исходный дескриптор, сделав его снова полезным.

3) Вы можете передать магический дескриптор, такой как дескриптор файла или ссылку на определенные объекты os /platform, и если вы установите правильные флаги, Binder создаст клон, указывающий на тот же ресурс для получателя, который на самом деле может использоваться на другом конце. Но это работает только для очень немногих типов объектов.

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

ответил Chris Stratton 23 22010vEurope/Moscow11bEurope/MoscowTue, 23 Nov 2010 08:32:16 +0300 2010, 08:32:16
0

Вы также можете использовать Gson для преобразования объекта в JSONObject и передачи его в связке. Для меня это был самый элегантный способ сделать это. Я не проверял, как это влияет на производительность.

В начальной деятельности

Intent activity = new Intent(MyActivity.this,NextActivity.class);
activity.putExtra("myObject", new Gson().toJson(myobject));
startActivity(activity);

В следующем задании

String jsonMyObject;
Bundle extras = getIntent().getExtras();
if (extras != null) {
   jsonMyObject = extras.getString("myObject");
}
MyObject myObject = new Gson().fromJson(jsonMyObject, MyObject.class);
ответил Laranjeiro 1 FebruaryEurope/MoscowbFri, 01 Feb 2013 16:09:02 +0400000000pmFri, 01 Feb 2013 16:09:02 +040013 2013, 16:09:02
0

Интерфейс Parcelable - это хороший способ передать объект с намерением.

Как сделать мои собственные объекты Parcelable? - довольно хороший ответ о том, как используйте Parcelable

Официальный Документы Google также содержит пример

ответил chris 23 22010vEurope/Moscow11bEurope/MoscowTue, 23 Nov 2010 00:47:43 +0300 2010, 00:47:43
0

Вы можете использовать глобальное состояние приложения .

Update:

Настройте и добавьте это в свой файл AndroidManifest.xml:

<application android:label="@string/app_name" android:debuggable="true" android:name=".CustomApplication"

А затем в вашем проекте есть такой класс:

package com.example;

import android.app.Application;

public class CustomApplication extends Application {
    public int someVariable = -1;
}

И потому что Доступ к нему можно получить через getApplication () из любого действия или Сервис ", вы используете его так:

CustomApplication application = (CustomApplication)getApplication();
application.someVariable = 123; 

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

ответил Neil 22 12010vEurope/Moscow11bEurope/MoscowMon, 22 Nov 2010 23:33:45 +0300 2010, 23:33:45
0

Вы также можете сделать свои объекты сериализуемыми и использовать набор getSerializable и putSerializable .

ответил dhaag23 23 22010vEurope/Moscow11bEurope/MoscowTue, 23 Nov 2010 01:29:48 +0300 2010, 01:29:48
0

Возможное решение:

Bundle bundle = new Bundle();
bundle.putSerializable("key", new CustomObject());

Класс CustomObject:

class CustomObject implements Serializable{
 private SubCustomObject1 sc1;
 private SubCustomObject2 sc2;
}

Пользовательские объекты:

class SubCustomObject1 implements Serializable{ }

class SubCustomObject2  implements Serializable{ }
ответил PraKhar 14 MonEurope/Moscow2015-12-14T18:10:26+03:00Europe/Moscow12bEurope/MoscowMon, 14 Dec 2015 18:10:26 +0300 2015, 18:10:26
0

Еще один способ отправки объектов через пакет - использование bundle.putByteArray
Пример кода

public class DataBean implements Serializable {
private Date currentTime;

public setDate() {
    currentTime = Calendar.getInstance().getTime();
 }

public Date getCurrentTime() {
    return currentTime;
 }
}

поместите объект DataBean в Bundle:

class FirstClass{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...

//When you want to start new Activity...
Intent dataIntent =new Intent(FirstClass.this, SecondClass.class);
            Bundle dataBundle=new Bundle();
            DataBean dataObj=new DataBean();
            dataObj.setDate();
            try {
                dataBundle.putByteArray("Obj_byte_array", object2Bytes(dataObj));

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }

            dataIntent.putExtras(dataBundle);

            startActivity(dataIntent);
}

Преобразование объектов в байтовые массивы

/**
 * Converting objects to byte arrays
 */
static public byte[] object2Bytes( Object o ) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream( baos );
      oos.writeObject( o );
      return baos.toByteArray();
    }

Получить объект обратно из Bundle:

class SecondClass{
DataBean dataBean;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...

//Get Info from Bundle...
    Bundle infoBundle=getIntent().getExtras();
    try {
        dataBean = (DataBean)bytes2Object(infoBundle.getByteArray("Obj_byte_array"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Метод для получения объектов из байтовых массивов:

/**
 * Converting byte arrays to objects
 */
static public Object bytes2Object( byte raw[] )
        throws IOException, ClassNotFoundException {
      ByteArrayInputStream bais = new ByteArrayInputStream( raw );
      ObjectInputStream ois = new ObjectInputStream( bais );
      Object o = ois.readObject();
      return o;
    }

Надеюсь, это поможет другим друзьям.

ответил Rupesh Yadav 11 TueEurope/Moscow2012-12-11T15:18:28+04:00Europe/Moscow12bEurope/MoscowTue, 11 Dec 2012 15:18:28 +0400 2012, 15:18:28
0

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

Применение

Во-первых, это приложение , так как о нем больше всего говорят об ответе. Вот. Приложение является хорошим объектом для размещения сущностей, которым нужна ссылка на Context. Для ServerSocket, несомненно, потребуется контекст (для файлового ввода-вывода или простых обновлений ListAdapter). Я лично предпочитаю этот маршрут. Мне нравятся приложения, они полезны для извлечения контекста (потому что они могут быть сделаны статическими и вряд ли вызовут утечку памяти) и имеют простой жизненный цикл.

Сервис

Сервис` занимает второе место. На самом деле `Service` - лучший выбор для моей проблемы, потому что именно для этого предназначены службы:
Сервис - это компонент приложения, который может выполнять длительные операции в
фон и не предоставляет пользовательский интерфейс.
Сервисы аккуратны тем, что имеют более определенный жизненный цикл, которым легче управлять. Кроме того, при необходимости службы могут запускаться извне приложения (т. Е. При загрузке). Это может быть необходимо для некоторых приложений или просто удобная функция.

Это не было полным описанием, но я оставил ссылки на документы для тех, кто хочет больше исследовать. В целом Service лучше подходит для нужного мне экземпляра - запуска ServerSocket для моего устройства SPP.

ответил ahodder 7 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 07 Sep 2012 20:22:38 +0400 2012, 20:22:38
0

Я столкнулся с этим вопросом, когда искал способ передать объект Date. В моем случае, как было предложено среди ответов, я использовал Bundle.putSerializable (), но это не сработало бы для такой сложной вещи, как описанный DataManager в исходном посте.

Мое предложение, которое даст очень похожий результат на размещение указанного DataManager в Приложении или на превращение его в Singleton, заключается в использовании Dependency Injection и привязке DataManager к области действия Singleton и внедрении DataManager везде, где это необходимо. Вы не только получите выгоду от улучшенной тестируемости, но также получите более чистый код без всякой базовой схемы «передачи зависимостей между классами и действиями». (Robo) Guice очень прост в работе, а новый Dagger также выглядит многообещающе.

ответил britzl 8 FebruaryEurope/MoscowbFri, 08 Feb 2013 00:41:59 +0400000000amFri, 08 Feb 2013 00:41:59 +040013 2013, 00:41:59
0

еще один простой способ передать объект с помощью пакета:

  • в объекте класса создайте статический список или другую структуру данных с ключом
  • когда вы создаете объект, поместите его в список /структуру данных с ключом (например, длинной меткой времени при создании объекта)
  • создайте метод static getObject (длинный ключ) для получения объекта из списка
  • в комплекте передайте ключ, чтобы вы могли получить объект позже из другой точки кода
ответил shaolin 24 ThuEurope/Moscow2015-12-24T12:46:00+03:00Europe/Moscow12bEurope/MoscowThu, 24 Dec 2015 12:46:00 +0300 2015, 12:46:00
0

1. Очень прямой и простой в использовании пример: передаваемый объект реализует Serializable.

class Object implements Serializable{
    String firstName;
   String lastName;
}

2.пропустить объект в комплекте

Bundle bundle = new Bundle();
Object Object = new Object();
bundle.putSerializable("object", object);
  1. получить переданный объект из пакета как Serializable, а затем привести к объекту.

    Object object = (Object) getArguments (). getSerializable ("object");

ответил king_T 21 AM00000010000003331 2018, 01:55:33

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132