Livraison intentionnelle de données complexes


Introduction à cette section :

Dans la section précédente, nous avons appris quelques utilisations de base de l'intention et découvert les sept attributs de l'intention, de l'intention explicite et Intentions implicites, et comment personnaliser les intentions implicites, et enfin vous fournir certaines intentions système couramment utilisées ! Ce que cette section vous expliquera, c'est le problème de la transmission des données par l'intention~D'accord, commençons cette section~


1 L'intention transmet des données simples

Aussi. Rappelez-vous comment nous avons appris dans Activity comment se transmettre des données simples entre deux activités ?

1.png

Vous pouvez directement enregistrer les données en appelant la méthode putExtra() de l'intention, puis appeler getXxxExtra après avoir obtenu l'intention. Type de données correspondant ; si plusieurs sont transmis, vous pouvez utiliser l'objet Bundle comme conteneur et transférer d'abord les données en appelant le putXxx de Bundle. Stockez-le dans le Bundle, puis appelez la méthode putExtras() de l'Intent pour stocker le Bundle dans l'Intent, puis après avoir obtenu l'Intent, Appelez getExtras() pour obtenir le conteneur Bundle, puis appelez son getXXX pour obtenir les données correspondantes ! De plus, le stockage des données est quelque peu similaire à celui de Map <key, value> !


2. L'intention transmet le tableau

Hé, les types normaux ne posent aucun problème, mais que se passe-t-il s'il s'agit d'un tableau ? La solution est la suivante :

Écrire dans un tableau :

bd.putStringArray("StringArray", new String[]{"haha" ," Haha"});
//Vous pouvez remplacer StringArray par d'autres types de données, tels que int, float, etc...

Lire le tableau :

String[] str = bd.getStringArray("StringArray")

3. L'intention transmet la collection

Eh bien, le tableau est très simple Bon, alors repassons la collection~ C'est un peu plus compliqué, et cela sera géré en fonction de la situation :


1) Liste<Type de données de base ou String>

Écrire la collection :

intent.putStringArrayListExtra(name, value)
intent.putIntegerArrayListExtra(name, value)

Lire la collection :

intent.getStringArrayListExtra(name)
intent.getIntegerArrayListExtra(name)

2) List< Object>

Forcer la liste dans un type sérialisable, puis la transmettre (le bundle peut être utilisé comme support)

Écrire dans la collection :

putExtras(clé, (Sérialisable)list)

Lire la collection :

(Liste<Objet> ;) getIntent().getSerializing(key)

PS : La classe Object doit implémenter l'interface Serialisable


3) Map<String, Object>, ou plus complexe

La solution est :Envelopper une liste dans la couche externe

//Passer des paramètres plus complexes
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("key1", "value1");
map1.put("key2", "value2");
List<Map<String, Object>> Map<String , Object>>();
list.add(map1);

Intent intent = new Intent(); ;
Bundle bundle = new Bundle();

//Une liste doit être définie pour transmettre l'ArrayList<Object> C'est nécessaire
ArrayList bundlelist = new. ArrayList() ;
bundlelist.add(list);
bundle.putParcelableArrayList("list",bundlelist);
intent.putExtras(bundle); 🎜>
4. >
Il existe deux manières de transmettre des objets : convertir l'objet en chaîne Json ou le sérialiser via Serialisable ou Parcelable Il n'est pas recommandé d'utiliser l'analyseur Json intégré à Android. Vous pouvez utiliser la bibliothèque tierce fastjson ou Gson !

1) Convertir un objet en chaîne Json

Exemple d'analyse Gson :


Modèle :

public class Author{

private int id; private String name; //...

}
public class Author{
private int id;
private String name;
//...
}



Écrire les données :

Livre livre =new Book();

book.setTitle("Java Programming Thoughts");Author author=new Author();author.setId(1);

author setName("Bruce. Eckel");
book.setAuthor(author);
Intent intent=new Intent(this,SecondActivity.class);
intent.putExtra("book",new Gson(). toJson(book) );
startActivity(intent);

读取数据:

String bookJson=getIntent().getStringExtra("book");
Book book=new Gson().fromJson(bookJson ,Book.class);
Log.d(TAG,"book title->"+book.getTitle());
Log.d(TAG,"book author name->"+book. getAuthor().getName());

2) Utilisez Serialisable, Parcelable pour sérialiser des objets


1 Implémentation sérialisable :

①Implémentation Business Bean : interface sérialisable. , écrivez les méthodes getter et setter
②Intent passe dans l'instance d'objet en appelant putExtra (String name, Serialised value) Bien sûr, s'il y a plusieurs objets, on peut aussi d'abord Bundle.putSerialised(x,x);
③La nouvelle Activity appelle la méthode getSerializingExtra() pour obtenir l'instance d'objet : Par exemple : Product pd = (Product) getIntent().getSerializingExtra("Product");
④Appelez la méthode get de l'objet pour obtenir les paramètres correspondants


2. implémentation :

Processus général :

①Les Business Beans héritent de l'interface Parcelable, remplacent la méthode writeToParcel et sérialisent votre objet en un objet Parcel ;
② Réécrire la méthodescribeContents, la description de l'interface de contenu, renvoyer 0 par défaut, bien sûr, s'il y a plusieurs objets, on peut d'abord Mettez Bundle.putParcelable(x,x) dans Bundle, puis Intent.putExtras() peut

Quelques explications :

Par writeToParcel Map votre objet dans un objet Parcel, puis mappez l'objet Parcel via createFromParcel devenez votre objet. Vous pouvez également considérer Parcel comme un flux et écrire des objets dans le flux via writeToParcel. Lire des objets du flux via createFromParcel, mais ce processus nécessite que vous l'implémentiez, alors écrivez L’ordre et l’ordre de lecture doivent être cohérents.

Exemple de code pour implémenter l'interface Parcelable :

//Interface de description interne,Vous n'avez pas besoin de gérer  
@Override  
public int describeContents() {  
     return 0 ;  
}  
       
      
 
@Override  
public void writeToParcel(Parcel parcel, int flags){  
    parcel.writeString(bookName);  
    parcel.writeString(auteur);  
    parcel.writeInt(publishTime);  
}  
      

public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {  
    @Override  
    public Book[] newArray(int size) {  
        return new Book[size] ;  
    }  
          
    @Override   
    public Book createFromParcel(Parcel source) {  
        Book mBook = new Book();    
        mBook.bookName = source.readString();   
        mBook.author = source.readString();    
        mBook.publishTime = source.readInt();   
        retourner mBook ;  
    }  
};

Android Studio génère le plug-in Parcleable :

Plug-in Intellij/Andriod Studio android-parcelable-intellij-plugin Tant que ALT+Insert, vous pouvez générer directement le code d'interface Parcleable.

De plus : les objets Parcelable sont largement utilisés dans Android et la mise en œuvre de l'interface Parcable est très lourde à utiliser. Framework open source tiers : Parceler, je ne l'ai pas encore essayé à cause de problèmes avec Maven.

Adresse de référence : [Généré automatiquement par Android Parcelable]

3. Comparaison de deux méthodes de sérialisation :

Comparaison entre les deux :

  • 1) Lors de l'utilisation de la mémoire, Parcelable a des performances supérieures à Seriallessly, il est donc recommandé d'utiliser Parcelable.
  • 2) Serialisable générera un grand nombre de variables temporaires lors de la sérialisation, provoquant des GC fréquents.
  • 3) Parcelable ne peut pas être utilisé lorsque les données doivent être stockées sur disque, car Parcelable ne peut pas garantir l'intégrité des données. Continuité face aux changements du monde extérieur. Bien que Serialisable soit moins efficace, il est toujours recommandé d'utiliser Serialisable pour le moment.

5. L'intention passe Bitmap

bitmap implémente l'interface Parcelable par défaut et peut être transmis directement

Code d'implémentation :

Bitmap bitmap = null;
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap) ;
intent.putExtra("bundle", bundle);

6. Il n'est pas pratique de les transmettre, définissez directement les données globales

Si vous transmettez des données simples et qu'il existe une telle demande, Activity1 -> Activité3 - > Activité4, Vous souhaitez transmettre certaines données d'Activity à Activity4, comment faire ? Pouvez-vous les transmettre de page en page ?

Évidemment non scientifique, non ? Si vous souhaitez que certaines données soient disponibles n'importe où, vous pouvez envisager d'utiliser l'Objet global Application !

Le système Android crée un objet Application lorsque chaque programme est en cours d'exécution, et un seul sera créé, donc Application Il s'agit d'une classe du modèle singleton et le cycle de vie de l'objet Application est le plus long de tout le programme. La période est égale au cycle de vie de ce programme. Si vous souhaitez stocker des valeurs plus statiques (fixes et immuables, mais pouvant également être modifiées), si vous souhaitez utiliser L'application a besoin d'une classe personnalisée pour implémenter la classe Application et indiquer au système que c'est notre application personnalisée qui est instanciée. Au lieu de la valeur par défaut du système, cette étape consiste à ajouter : attribut de nom à notre balise d'application dans AndroidManifest.xml !

Partie clé du code :

1) Classe d'application personnalisée :

classe MyApp extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}

2) Déclaration dans AndroidManifest.xml :

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

3) Appelez si nécessaire :

class Blah étend l'activité {
@Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}

Écriture haute définition

 : L'objet global Application peut être obtenu à n'importe quel endroit.


Applicaiton est un composant du système. Il a également son propre cycle de vie. Nous pouvons l'obtenir dans onCraete. Objet applicatif. Postez le code modifié !

class MyApp étend l'application {
private String myState;
instance MyApp statique privée;

public static MyApp getInstance(){
instance de retour;
}
 
 
 public String getState(){
 return myState;
}
public void setState(String s){
 myState = s;
}

@Override
public void onCreate(){
onCreate();
instance = this;
}

}

Ensuite, nous pouvons appeler directement : MyApp.getInstance() n'importe où pour obtenir l'objet global de Application !


Remarque :

L'objet Application existe en mémoire et il peut être supprimé par le système, comme dans ce scénario :

Nous stockons le compte utilisateur dans l'application dans Activity1, puis obtenons le compte utilisateur dans Activity2 et l'affichons !

Si nous cliquons sur le bouton d'accueil puis attendons N longtemps, le système tuera notre application afin de récupérer de la mémoire. A ce moment, nous re- Ouvrez cette application, c'est magique à ce moment, vous revenez sur la page Activité2, mais si vous récupérez l'Application à ce moment Si le compte utilisateur est saisi, le programme signalera une NullPointerException puis plantera ~

La raison pour laquelle le crash ci-dessus se produit est que l'objet Application est nouvellement créé. Vous pouvez penser que l'application est redémarrée. En fait, ce n'est pas le cas, créez simplement une nouvelle application, puis démarrez l'activité lorsque l'utilisateur est parti la dernière fois, créant ainsi l'application. Il n'y a aucune illusion d'être tué ! Par conséquent, s’il s’agit de données plus importantes, il est également recommandé de les localiser lors de l’utilisation des données. Vérifiez la valeur de la variable pour la non-nullité ! Un autre point est le suivant : cela n'est pas seulement vrai pour les variables d'application, mais également pour les objets singleton et les variables statiques publiques. Ce sera aussi comme ça ~


7. Passage des paramètres du mode Singleton

L'application ci-dessus est basée sur un mode singleton. qu'il peut garantir que la classe système A a exactement une instance. Ceci est très simple à réaliser, en définissant les paramètres en A et en y accédant directement en B. C'est la plus efficace parmi plusieurs méthodes.

Exemple de code : (le code vient d'Internet~)

①Définir une classe singleton  :

classe publique XclSingleton
{
//Instance en mode Singleton
private static Créer une instance
public synchronisé statique XclSingleton getInstance(){
if(instance == null){
instance = new XclSingleton();
}
return instance;

final HashMap<String, Object>
private XclSingleton()
{ 🎜> }

public void put(String key,Object value){
mMap.put(key,value);
}
public Object get(String key)
{
return mmM ap.get (key);
}
("key1", "value1");
XclSingleton.getInstance().put("key2", "value2");



Résumé de cette section :

D'accord, c'est tout sur la transmission de données complexes Intent. En plus d'utiliser Intent pour transmettre des données complexes, cette section vous apprend également. Utilisez les modèles d'application et singleton pour transmettre les paramètres ! Je pense que cela apportera de la commodité à tout le monde dans la transmission de données, merci~