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

Android intent之间复杂参数传递方法详解

Questo articolo descrive in dettaglio i metodi di trasmissione dei parametri complessi tra i vari intent di Android. Condivido questo con tutti voi per riferimento, come segue:

Intent è il mezzo di trasmissione dei parametri tra Activity e Activity, tra Activity e Service, e solitamente si realizza la trasmissione di tipi di oggetti Java di base e String.
In progetti reali, oltre ai metodi menzionati, ci sono spesso esigenze di passaggio di oggetti Object, tipi List, List<Object> e variabili globali. Questo articolo spiega come passare questi tipi di parametri.

1. Passaggio di List<String> e List<Integer>

Ecco un esempio per inviare List<String>:

intent.putStringArrayListExtra(key, list);

La sintassi per ricevere List<String> è:

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

Ecco un esempio di applicazione:

// =============Invio di 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);
// ====================Ricezione di List<String>======================
ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");

Operazioni simili a List<Integer> possono essere realizzate chiamando il seguente metodo per inviare e ricevere:

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

Secondo, utilizzare i metodi Serializable e Parcelable per passare Object

Ci sono due metodi per passare oggetti tra Intent in Android: uno è Bundle.putSerializable(Key, Object); l'altro è Bundle.putParcelable(Key, Object). L'oggetto Object deve soddisfare determinate condizioni, dove il primo ha implementato l'interfaccia Serializable e l'altro ha implementato l'interfaccia Parcelable.

Di seguito è riportata la classe User che ha implementato l'interfaccia Serializable, denominata SerializableUser esclusivamente per facilitare la distinzione tra la classe User che ha implementato l'interfaccia Parcelable, non consigliata per l'uso in sviluppo reale:

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

Di seguito è riportata la classe User che ha implementato l'interfaccia 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 metodo generato automaticamente
    return 0;
  }
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    // TODO metodo generato automaticamente
    dest.writeString(userName);
    dest.writeString(password);
  }
}

usando due metoditrasmissioneLa sintassi è rispettivamente:

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

usando due metodiricezioneLa sintassi è rispettivamente:

object=(Object) getIntent().getSerializableExtra(key);
object=(Object) getIntent().getParcelableExtra(key);
// ===========Usare Serializable e Parcelable per inviare l'oggetto===========
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);
// ====================Receiving Object======================
SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser");
ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");

Someone may notice that implementing Serializable interface is essentially serializing objects and then transmitting them, which has no obvious difference from common Java programming, and User does not need to change significantly, which is relatively simple. I also recommend using this method.

However, the latter implementation of Parcelable interface is more complex. What is Parcelable?

Android provides a new type: Parcel, which is used as a container for encapsulating data. Encapsulated data can be passed through Intent or IPC. In addition to basic types, only classes that implement Parcelable interface can be placed in Parcel.

To implement Parcelable interface, it is necessary to implement three methods:

1) writeToParcel method. This method writes the data of the class into the Parcel provided externally.
Declaration: writeToParcel (Parcel dest, int flags).

2) describeContents method. Just return 0.

3) Static interface Parcelable.Creator<T>, this interface has two methods:

createFromParcel(Parcel in) implementa la funzione di creare un'istanza della classe da in.
newArray(int size) crea un array di tipo T della lunghezza size, return new T[size]; è sufficiente. Questo metodo è utilizzato per deserializzare array esterni di questa classe.

Attraverso l'output di log di test è possibile conoscere lo stato di esecuzione del programma, quando si chiama bundle.putParcelable("parcelableUser", parcelableUser);, viene chiamato il metodo public void writeToParcel(Parcel dest, int flags) della classe ParcelableUser, e si scrivono dati su dest, quando ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");, viene chiamato il metodo public ParcelableUser createFromParcel(Parcel source) della classe ParcelableUser per creare un oggetto ParcelableUser, assegnare valori alle proprietà di questo oggetto, qui Parcel source e Parcel dest sono gli stessi, quindi restituisce l'oggetto ParcelableUser. Infine, è possibile stampare le informazioni delle proprietà di parcelableUser.

3. Trasmissione di List<Object>

Se dobbiamo trasmettere una lista List<Object> composta da oggetti Object, cosa dovremmo fare? Prima di tutto, è necessario implementare l'interfaccia Serializable per l'oggetto Object, quindi convertire la lista in tipo Serializable e infine trasmettere tramite:

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

Questa sintassi viene utilizzata per trasmettere, e il destinatario deve anche eseguire la conversione di tipo forzata in List<Object> quando riceve, la sintassi utilizzata per ricevere List<Object> è:

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

Ecco un esempio di applicazione, qui il tipo SerializableUser è stato fornito nel passaggio precedente e non verrà ripetuto qui.

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

Quattro, variabili globali

Se ci sono parametri di livello applicazione speciali che non sono comodi da trasmettere tramite intent, ci si potrebbe chiedere se ci sono variabili globali o statiche che possano essere utilizzate? Le variabili statiche di Java sono adatte in questo contesto, ma il loro valore viene perso dopo che l'Activity ha chiamato System.exit(0) o finish().

In Android c'è un modo più elegante di utilizzare ApplicationContext. Questo metodo per le variabili globali è più sicuro rispetto alle classi statiche, poiché le variabili vengono liberate solo dopo che tutti gli Activity dell'applicazione sono stati distrutti.

Il SDK di Android menziona che l'Application serve per salvare le variabili globali e esiste già alla creazione del package. Pertanto, quando è necessario creare variabili globali, non è necessario creare variabili statiche con permessi public come in J2SE, ma è sufficiente implementarle nell'application. È sufficiente chiamare getApplicationContext di Context o getApplication di Activity per ottenere un'istanza di Application e impostare o leggere il valore della variabile globale.

Quando si avvia l'Application, il sistema crea un PID, ovvero l'ID del processo, e tutte le Activity eseguiranno su questo processo. Quindi inizializziamo le variabili globali quando si crea l'Application, tutte le Activity della stessa applicazione possono ottenere i valori di queste variabili globali. In altre parole, se cambiamo i valori di queste variabili globali in un'Activity, i valori cambieranno anche nelle altre Activity della stessa applicazione.

Uso:

1. Crea una sottoclasse di android.app.Application che tu stessa crei, e aggiungi i metodi setter e getter per le variabili globali private che desideri condividere.

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

2. Dichiarare questa classe nel manifest, quindi Android ne crea un'istanza globale disponibile.

In realtà, è aggiungere un nome all'etichetta application esistente, che rappresenta questa istanza globale.

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

3. Puoi utilizzare il metodo Context.getApplicationContext() in qualsiasi altro luogo per ottenere questa istanza e ottenere lo stato (variabili) al suo interno.

// ============ Utilizzo delle variabili globali per passare parametri ============
MyApp myApp = ((MyApp) getApplicationContext()); // Otteniamo la nostra applicazione MyApp
myApp.setGlobalVariable("variabile globale");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, GlobalActivity.class);
startActivity(intent);
// ============ Ricezione dei parametri della variabile globale ============
MyApp myApp = ((MyApp) getApplicationContext());
String globalVariable = myApp.getGlobalVariable();

Chi è interessato a ulteriori contenuti relativi a Android può consultare le sezioni speciali di questo sito: 'Guida di introduzione e avanzamento per lo sviluppo Android', 'Concetti di operazione di activity nel programming Android', 'Concetti di operazione delle risorse Android', 'Concetti di operazione dei file Android', 'Concetti di operazione del database SQLite Android', 'Concetti di operazione dei dati JSON Android', 'Concetti di operazione del database Android', 'Metodi di operazione della scheda SD nel programming Android', 'Concetti di operazione delle viste View Android' e 'Concetti di utilizzo dei controlli Android'.

Spero che il contenuto di questo articolo possa essere utile per la progettazione di applicazioni Android.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi proprietari. Il contenuto è stato contribuito volontariamente dagli utenti di Internet e caricato autonomamente. Questo sito non detiene i diritti di proprietà, non ha effettuato alcuna modifica editoriale e non assume alcuna responsabilità legale correlata. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a notice#oldtoolbag.com (al momento dell'invio, sostituisci # con @) per segnalare il problema e fornire prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.