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

Detalhamento da transmissão de parâmetros complexos entre intents do Android

Este artigo detalha métodos complexos de transmissão de parâmetros entre intents no Android. Compartilho com vocês para referência, conforme detalhado a seguir:

Intent é o meio de transmissão de parâmetros entre Activity e Activity, Activity e Service, e esses dois geralmente implementam a transmissão de tipos de objetos básicos do Java e String.
Em projetos reais, além das várias maneiras mencionadas acima, frequentemente há a necessidade de passar objetos Object, tipos List, List<Object> e variáveis globais etc. Este artigo visa explicar como passar esses tipos de parâmetros.

1. Passar List<String> e List<Integer>

A seguir, com um exemplo de envio de List<String>, a sintaxe para enviar List<String> é:

intent.putStringArrayListExtra(key, list);

A sintaxe para receber List<String> é:

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

A seguir, um exemplo de uso:

// =============Enviar List<String>=============
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("string",1");
stringList.add("string",2");
stringList.add("string",3");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, StringListActivity.class);
intent.putStringArrayListExtra("ListString", stringList);
startActivity(intent);
// ====================Receber List<String>======================
ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");

Para operações semelhantes a List<Integer>, você pode chamar o método a seguir para enviar e receber:

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

II - Uso dos métodos Serializable e Parcelable para passar Objetos

Existem duas maneiras de passar objetos entre Intents no Android: uma é Bundle.putSerializable(Key, Object); e a outra é Bundle.putParcelable(Key, Object). O objeto Object deve atender a certas condições, o primeiro implementou a interface Serializable, e o segundo implementou a interface Parcelable.

A seguir está a classe User que implementou a interface Serializable, chamada SerializableUser apenas para facilitar a distinção da classe User que implementou a interface Parcelable, não é recomendável fazer isso em desenvolvimento real:

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

A seguir está a classe User que implementou a interface Parcelable:

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 Auto-gambito de método gerado automaticamente
    return 0;
  }
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    // TODO Auto-gambito de método gerado automaticamente
    dest.writeString(userName);
    dest.writeString(password);
  }
}

usando dois métodostransmissãoa sintaxe é respectivamente:

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

usando dois métodosrecepçãoa sintaxe é respectivamente:

object=(Object) getIntent().getSerializableExtra(key);
object = (Object) getIntent().getParcelableExtra(key);
// ==========Usar Serializable e Parcelable para enviar Object respectively===========
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);
// ====================Receber Object======================
SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser");
ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");

Alguém pode notar que implementar a interface Serializable é serializar o objeto e, em seguida, transmitir, sem diferença significativa no código de programação comum do Java, e o User não precisa ser alterado significativamente, o que é simples. Eu também recomendo usar essa maneira.

No entanto, a implementação Parcelable dessas classes é mais complexa, o que é Parcelable?

O Android oferece um novo tipo: Parcel, usado como contêiner para encapsular dados, e os dados encapsulados podem ser transmitidos através de Intent ou IPC. Além dos tipos básicos, apenas as classes que implementam a interface Parcelable podem ser colocadas no Parcel.

Para implementar a interface Parcelable, é necessário implementar três métodos:

1A função writeToParcel. Este método escreve os dados da classe no Parcel fornecido externamente.
Declarar: writeToParcel(Parcel dest, int flags).

2A função describeContents. Basta retornar 0.

3A interface Parcelable.Creator<T> estática, essa interface tem dois métodos:

createFromParcel(Parcel in) implementa a função de criar instâncias da classe a partir de in.
newArray(int size) cria um array do tipo T com tamanho size, return new T[size]; é suficiente. Este método é fornecido para desserialização de arrays externos dessa classe.

Através do teste de log de saída, podemos verificar o estado de execução do programa. Quando chamamos bundle.putParcelable("parcelableUser", parcelableUser);, chamamos o método public void writeToParcel(Parcel dest, int flags) da classe ParcelableUser e escrevemos dados em dest. Quando ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");, chamamos o método public ParcelableUser createFromParcel(Parcel source) da classe ParcelableUser para criar um objeto ParcelableUser, atribuir valores às propriedades deste objeto. Aqui, Parcel source e Parcel dest são os mesmos, e retornamos o objeto ParcelableUser. Finalmente, podemos imprimir as informações das propriedades de parcelableUser.

Três, passar List<Object>

Se queremos passar uma lista composta por Object, ou seja, List<Object>, o que devemos fazer? Primeiro, é necessário que o objeto Object implemente a interface Serializable, em seguida, forçar a conversão do tipo da lista para Serializable, e finalmente, através de:

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

Esta sintaxe é usada para passar, e o destinatário também precisa fazer a conversão de tipo forçada para List<Object> ao receber, a sintaxe usada para receber List<Object> é: }}

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

A seguir está um exemplo de aplicação, aqui o uso da classe SerializableUser foi fornecido no passo anterior e não será repetido aqui.

// ==============Enviar 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);
// ====================Receber List<Object>======================
List<SerializableUser> objectList = (List<SerializableUser>) getIntent().getSerializableExtra("ListObject");

Quarto, variáveis globais

Se alguns parâmetros de nível de aplicativo específicos não forem convenientes para passar parâmetros usando intent, é fácil pensar se há variáveis globais ou estáticas que podem ser usadas? As variáveis estáticas em Java são apropriadas aqui, mas seu valor é perdido após a chamada do System.exit(0) ou finish() pelo Activity.

No Android, há uma maneira mais elegante de usar o ApplicationContext. Este método de variável global é mais seguro em comparação com a classe estática, e só é liberado após o destory de todos os Activitys do aplicativo.

No SDK do Android há uma menção de que a Application é usada para armazenar variáveis globais e já existe no momento da criação do pacote. Portanto, quando precisamos criar variáveis globais, não precisamos mais como J2SE precisa criar variáveis estáticas publicas de permissão, enquanto diretamente implementamos no application. Basta chamar o método getApplicationContext do Context ou getApplication da Activity para obter um objeto Application e configurar ou ler os valores das variáveis globais.

Quando o Application é iniciado, o sistema cria um PID, ou seja, o ID do processo, todas as Activities serão executadas neste processo. Portanto, inicializamos as variáveis globais no momento da criação do Application, todas as Activities da mesma aplicação podem obter os valores dessas variáveis globais. Em outras palavras, se alterarmos os valores dessas variáveis globais em alguma Activity, os valores também mudarão em outras Activities da mesma aplicação.

Uso:

1. Crie uma subclasse do android.app.Application que você mesmo, adicione métodos setter e getter para os variáveis globais privados que deseja compartilhar.

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

2. Declare essa classe no manifest, e o Android criará uma instância global disponível nessa hora.

Na verdade, é definir um nome para essa instância global no único rótulo application existente.

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

3. Pode usar o método Context.getApplicationContext() em qualquer lugar para obter essa instância e, em seguida, obter o estado (variáveis) dentro dela.

// ============Utilizar variáveis globais para passar parâmetros==============
MyApp myApp = ((MyApp) getApplicationContext());//Obtenha nosso aplicativo MyApp
myApp.setGlobalVariable("Variável Global");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, GlobalActivity.class);
startActivity(intent);
// ============ Parâmetros de Recepção de Variáveis Globais ============
MyApp myApp = ((MyApp) getApplicationContext());
String globalVariable = myApp.getGlobalVariable();

Leitores interessados em mais conteúdo sobre Android podem consultar as seções especializadas deste site: 'Tutorial de Entrada e Avançado de Desenvolvimento Android', 'Resumo de Técnicas de Operação de Activity em Programação Android', 'Resumo de Técnicas de Operação de Recursos Android', 'Resumo de Técnicas de Operação de Arquivos Android', 'Resumo de Técnicas de Operação de Banco de Dados SQLite Android', 'Resumo de Técnicas de Operação de Dados no Formato JSON Android', 'Resumo de Técnicas de Operação de Banco de Dados Android', 'Resumo de Técnicas de Operação de Cartão SD no Desenvolvimento Android', 'Resumo de Técnicas de View Android' e 'Resumo de Uso de Controles Android'

Espero que o que é mencionado neste artigo ajude os amigos no design de programas Android.

Declaração: o conteúdo deste artigo é extraído da Internet, pertencendo ao autor original. O conteúdo é contribuído e carregado voluntariamente pelos usuários da Internet. Este site não possui direitos de propriedade, não foi editado artificialmente e não assume responsabilidade legal relevante. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie e-mail para: notice#oldtoolbag.com (ao enviar e-mail, substitua # por @ para denunciar, e forneça provas relevantes. Atingida, o site deletará imediatamente o conteúdo suspeito de violação de direitos autorais.)

Você também pode gostar