English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Подробное объяснение метода передачи сложных параметров между Android intent

Эта статья подробно рассказывает о сложных методах передачи параметров между Android intent. Предлагается к рассмотрению, см. подробнее:

Intent является средством передачи параметров между Activity и Activity, Activity и Service, и обычно реализует передачу Java базовых типов объектов и String.
На практике, передача значений между страницами, помимо вышеупомянутых, часто требует передачи объектов Object, типов List, List<Object> и глобальных переменных и т.д. Эта статья рассказывает о том, как передавать эти типы параметров.

1. Передача List<String> и List<Integer>

Ниже приведен пример для передачи List<String>:

intent.putStringArrayListExtra(key, list);

Синтаксис получения List<String>:

list = (ArrayList<String>)getIntent().getStringArrayListExtra(key);

Ниже приведен пример использования:

// ============= Отправка List<String> ==============
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("string1");
stringList.add("string2");
stringList.add("string3");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, StringListActivity.class);
intent.putStringArrayListExtra("ListString", stringList);
startActivity(intent);
// ==================== Получение List<String> ======================
ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");

Операции, аналогичные List<Integer>, можно также реализовать с помощью следующих методов для отправки и приема:

intent.putIntegerArrayListExtra(key, list);
list =(ArrayList<Integer>) getIntent().getIntegerArrayListExtra(key);

二、使用Serializable和Parcelable两种方式传递Object

Android的Intent之间传递对象有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcelable(Key,Object)。方法中的Object要满足一定的条件,前者实现了Serializable接口,而后者实现了Parcelable接口。

以下是实现了Serializable接口的User类,命名为SerializableUser纯粹是从类名方便区分实现了Parcelable接口的User类,实际开发中不建议这么命名:

public class SerializableUser implements Serializable {
  private String userName;
  private String password;
  public SerializableUser() {
  }
  public SerializableUser(String userName, String password) {
    this.userName = userName;
    this.password = password;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
}

以下是实现了Parcelable接口的User类:

public class ParcelableUser implements Parcelable {
  private String userName;
  private String password;
  public ParcelableUser() {
  }
  public ParcelableUser(String userName, String password) {
    this.userName = userName;
    this.password = password;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public static final Parcelable.Creator<ParcelableUser> CREATOR = new Creator<ParcelableUser>() {
    @Override
    public ParcelableUser createFromParcel(Parcel source) {
      ParcelableUser parcelableUser = new ParcelableUser();
      parcelableUser.userName = source.readString();
      parcelableUser.password = source.readString();
      return parcelableUser;
    }
    @Override
    public ParcelableUser[] newArray(int size) {
      return new ParcelableUser[size];
    }
  };
  @Override
  public int describeContents() {
    // TODO Автоматически сгенерированный метод
    return 0;
  }
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    // TODO Автоматически сгенерированный метод
    dest.writeString(userName);
    dest.writeString(password);
  }
}

Используя два способаПередачаГрамматика соответственно:

bundle.putSerializable(key, object);
bundle.putParcelable(key, object);

Используя два способаПолучениеГрамматика соответственно:

object = (Object) getIntent().getSerializableExtra(key);
object = (Object) getIntent().getParcelableExtra(key);
// ============== Использование Serializable и Parcelable для отправки объекта ==============
SerializableUser serializableUser = new SerializableUser("user1", "123456");
ParcelableUser parcelableUser = new ParcelableUser("user2", "654321");
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putSerializable("serializableUser", serializableUser);
bundle.putParcelable("parcelableUser", parcelableUser);
intent.setClass(ListDemoActivity.this, ObjectActivity.class);
intent.putExtras(bundle);
startActivity(intent);
// ==================== Получение объекта ====================
SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser");
ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");

Возможно, кто-то заметил, что реализация интерфейса Serializable означает сериализацию объекта, а затем передачу его, что не имеет明显的 отличий от обычной программирования на Java, и User не требует значительных изменений, это просто. Я также рекомендую использовать этот способ.

Однако, второй способ реализации интерфейса Parcelable сложнее. Что такое Parcelable?

Android предоставляет новый тип: Parcel, который используется в качестве контейнера для данных. После封装 данные можно передавать через Intent или IPC. Кроме базовых типов, только классы, реализующие интерфейс Parcelable, могут быть добавлены в Parcel.

Для реализации интерфейса Parcelable необходимо реализовать три метода:

1) Метод writeToParcel. Этот метод записывает данные класса в Parcel, предоставленный извне.
Декларация: writeToParcel(Parcel dest, int flags).

2) Метод describeContents. Достаточно просто вернуть 0.

3) Статический интерфейс Parcelable.Creator<T>, который имеет два метода:

createFromParcel(Parcel in) реализует функцию создания экземпляра класса из in.
newArray(int size) создает массив типа T длиной size, return new T[size];. Этот метод предназначен для использования внешними классами для десериализации массива этого класса.

Для тестирования работы программы с помощью log выводятся результаты выполнения, при вызове bundle.putParcelable("parcelableUser", parcelableUser); вызывается метод public void writeToParcel(Parcel dest, int flags) класса ParcelableUser, и данные записываются в dest, при ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser"); вызывается метод public ParcelableUser createFromParcel(Parcel source) класса ParcelableUser, создается объект ParcelableUser, и ему задаются значения свойств, где Parcel source и Parcel dest являются одинаковыми, затем возвращается объект ParcelableUser. В конце можно напечатать информацию о свойствах parcelableUser.

Третий раздел: передача List<Object>

Если мы хотим передать список, состоящий из объектов Object, то есть List<Object>, что нужно сделать? Сначала необходимо реализовать интерфейс Serializable для объекта Object, затем преобразовать список в тип Serializable, и finally передать его через:

Intent.putExtra(key, (Serializable) objectList);

Такой синтаксис используется для передачи, и получатель также должен强制 преобразовать тип при получении в List<Object>, синтаксис для получения List<Object>:

objectList = (List<Object>) getIntent().getSerializableExtra(key);

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

// ==============Send List<Object>===========
SerializableUser user1 = new SerializableUser("user1", "123456");
SerializableUser user2 = new SerializableUser("user2", "654321");
List<SerializableUser> objectList = new ArrayList<SerializableUser>();
objectList.add(user1);
objectList.add(user2);
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, ObjectListActivity.class);
intent.putExtra("ListObject", (Serializable) objectList);
startActivity(intent);
// ==================== Получение List<Object> ====================
List<SerializableUser> objectList = (List<SerializableUser>) getIntent().getSerializableExtra("ListObject");

Четыре, глобальные переменные

Если某些 специфические параметры уровня приложения不方便使用 intent для передачи параметров, легко предположить, что можно использовать глобальные переменные или статические переменные? Статические переменные Java подходят здесь, но их значения теряются после того, как Activity вызовет System.exit(0) или finish().

В Android есть более изящный способ использования ApplicationContext. Этот метод глобальных переменных более надежен по сравнению с статическими классами и будет освобожден только после того, как все Activity приложения будут уничтожены.

В SDK Android говорится, что Application предназначен для хранения глобальных переменных и существует с момента создания пакета. Поэтому, когда нам нужно создать глобальные переменные, нам не нужно создавать статические переменные с правами public, как в J2SE, а напрямую реализовывать их в application. Достаточно вызвать метод getApplicationContext из Context или getApplication из Activity, чтобы получить объект Application и можно устанавливать или считывать значения глобальных переменных.

При запуске приложения система создает PID (идентификатор процесса), и все Activity работают в этом процессе. Поэтому при создании приложения инициализируем глобальные переменные, и все Activity в этом приложении могут получить значения этих глобальных переменных. Иначе говоря, если мы изменим значение этих глобальных переменных в одном Activity, это изменение будет видимо в других Activity того же приложения.

Пример использования:

1. Создайте подкласс android.app.Application, добавьте методы setter и getter для private глобальных переменных, которые вы хотите делиться.

public class MyApp extends Application{
  private String globalVariable;
  public String getGlobalVariable() {
    return globalVariable;
  }
  public void setGlobalVariable(String globalVariable) {
    this.globalVariable = globalVariable;
  }
}

2. Укажите этот класс в манифесте, и Android создаст глобальную инстанцию, доступную для использования.

Это означает, что на существующем единственном теге application мы определяем имя для этой глобальной инстанции.

<application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name">

3. В других местах можно использовать метод Context.getApplicationContext() для получения этой инстанции и доступа к её состоянию (переменным).

// ============ Использование глобальных переменных для передачи параметров ============
MyApp myApp = ((MyApp) getApplicationContext()); // Получаем наше приложение MyApp
myApp.setGlobalVariable("Глобальная переменная");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, GlobalActivity.class);
startActivity(intent);
// ============ Получение параметров глобальных переменных =============
MyApp myApp = ((MyApp) getApplicationContext());
String globalVariable = myApp.getGlobalVariable();

Дополнительную информацию о разработке Android, интересующие читатели, могут найти в разделе сайта: «Введение в разработку Android и продвинутые руководства», «Суммарные советы по работе с activity в Android», «Сборник советов по работе с ресурсами в Android», «Сборник советов по работе с файлами в Android», «Суммарные советы по работе с базами данных SQLite в Android», «Суммарные советы по работе с json-данными в Android», «Сборник советов по работе с базами данных в Android», «Сборник методов работы с SD-картой в Android», «Суммарные советы по работе с видами View в Android» и «Сборник советов по использованию контроллеров в Android»

Надеюсь, что информация, изложенная в этой статье, поможет вам в разработке приложений для Android.

Объявление: содержимое этой статьи взято из интернета, авторские права принадлежат соответствующему автору. Контент предоставлен пользователями интернета, автоматически загружен, сайт не имеет права собственности, не был отредактирован вручную и не несет ответственности за него. Если вы обнаружите материалы,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма, пожалуйста, замените # на @) для сообщения о нарушении и предоставьте соответствующие доказательства. При подтверждении факта нарушения, сайт немедленно удалят материалы,涉嫌侵权.

Рекомендуется для просмотра