3
votes

Pourquoi mon ArrayList affiche-t-il une taille de zéro lorsqu'il est connecté à partir de la méthode principale mais affiche une taille d'un certain nombre lorsqu'il est appelé à partir d'une méthode intern

Je crée un programme de distributeur automatique en utilisant Firebase où chaque fois qu'une valeur est mise à jour dans la base de feu, elle est extraite dans la classe "NewUt" et ajoutée à l'ArrayList "allLocations". J'ai Log.d () dans la méthode onCreate qui imprime la taille du tableau et un autre Log.d () dans la méthode onDataChange lorsque les données sont mises à jour. Le Log.d () dans le onCreate montre que le tableau a une taille de 0 mais le Log.d () dans la méthode onDataChange affiche une taille supérieure à zéro. Quel pourrait être le problème?

J'ai essayé de mettre onDataChange dans une méthode différente mais toujours les mêmes résultats.

D/ArraySize: Size is 4
D/ArraySize: Size is 5
D/ArraySize: Size is 6
D/ArraySize: Size is 10

Log.d () dans la méthode onCreate.

D/RefFromMain: Size is 0
D/RefFromMain: Size is 0
D/RefFromMain: Size is 0
D/RefFromMain: Size is 0

Log.d () dans la méthode onDataChange.

package com.xeon.vendingmachine;

import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Camera;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MapsActivity extends FragmentActivity implements 
OnMapReadyCallback {

private GoogleMap mMap;
DatabaseReference myRef;
private static ArrayList<Utilities> allLocations = new ArrayList<>();




@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    FirebaseApp.initializeApp(this);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    myRef = FirebaseDatabase.getInstance().getReference("Vending Machines");
    Random r = new Random();
    Double randLat = r.nextDouble()*100;
    Double randLon = r.nextDouble()*100;
   Utilities utilitiesForDatabase = new Utilities(randLat,randLon,"Carol Machifne","Carfol","Layfs","Ffull");
     String uid = myRef.push().getKey();
     myRef.child(uid).setValue(utilitiesForDatabase);
    String TAG  = "RefFromMain";
   myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            allLocations.clear();

            for (DataSnapshot allLocs : dataSnapshot.getChildren()) {
                Utilities newUt = allLocs.getValue(Utilities.class);
                allLocations.add(newUt);
            }


            Log.d("ArraySize" , "Size is " + allLocations.size());
            Log.d("LatLng" , " New Lattitude : " + allLocations.get(allLocations.size()-1).getLattitude() + " Longitude : " + allLocations.get(allLocations.size()-1).getLongitude());
             NotificationCompat.Builder mBuilderArray =
                    new NotificationCompat.Builder(getApplicationContext())
                            .setContentTitle("New location added")
                            .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
                            .setContentText("Size is " + allLocations.size());

            NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(1,mBuilderArray.build());

        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.e("Database Error", "The data could not be extracted");
        }
    });
    Log.d(TAG , "Size is " + this.allLocations.size());

}


@Override
public void onMapReady(GoogleMap googleMap) {

    mMap = googleMap;



}


}


0 commentaires

3 Réponses :


4
votes
          allLocations.add(newUt);
        }
        Log.d("ArraySize" , "Size is " + allLocations.size());

0 commentaires

2
votes

Vous avez enregistré la taille du tableau dans main après l'allocation. Donc c'est 0. Mais dans onDataChange vous avez mis des données dans ce tableau avec allLocations.add (newUt); . Donc, il affiche la taille égale au nombre de données insérées.


10 commentaires

Alors, comment puis-je le programmer de manière à ce que lorsque le tableau est rempli dans onDataChange, il soit également rempli dans onCreate?


Voulez-vous enregistrer les données dans la liste des tableaux après leur chargement une fois?


Si vous voulez comme je l'ai dit dans le commentaire précédent, vous devez rendre la liste des tableaux statique et allouer de la mémoire en dehors de la méthode onCreate. comme provate static ArrayList allLocations = new ArrayList <> (); et supprimez cette ligne à partir de create `allLocations = new ArrayList <> ();` et supprimez cette ligne de onDataChanged allLocations.clear ();


Je veux donc que le tableau ne contienne que les valeurs mises à jour de la méthode onDataChange () et je veux faire en sorte que je puisse utiliser les données du tableau de n'importe où dans la classe.


Pour obtenir ce que vous voulez, vous devez faire la même chose que je l'ai indiqué dans le dernier commentaire. SAUF, vous devez conserver allocations.clear (); dans la méthode `onDataChange '.


J'ai fait exactement ce que vous avez dit, mais maintenant, il conserve les données précédemment mises à jour et y ajoute les nouvelles données mises à jour.


veuillez ne pas supprimer allLocations.clear (); si vous souhaitez uniquement mettre à jour les données.


Je ne l'ai pas supprimé


J'ai mis à jour mon code comme vous l'avez suggéré. Mais, malheureusement, je reçois les mêmes résultats.


c'est très malheureux neel. veuillez essayer le débogage pour avoir un aperçu de ce qui se passe là-bas. Comment déboguer dans Android Studio



0
votes

Au début, vous initiez votre Arraylist. ici

 myRef.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            allLocations.clear();
            for (DataSnapshot allLocs : dataSnapshot.getChildren()) {
                Utilities newUt = allLocs.getValue(Utilities.class);
              allLocations.add(newUt);
            }

Donc, il initialise avec des données vides. il n'y a rien dedans. Ensuite, dans addValueEventListener , vous ajoutez des données à votre allLocations ArrayList.

 allLocations = new ArrayList<>();
    Log.d(TAG , "Size is " + allLocations.size());

Alors maintenant, il contient des valeurs.


20 commentaires

alors y a-t-il un moyen de le programmer pour que les deux résultats soient les mêmes?


@NeelPatel Err, imprimer la taille après l'appel de la méthode?


Oui. sinon, si vous avez des données antérieures à addValueEventListener , vous pouvez également les ajouter manuellement. par allLocations.add ("vos données")


addValueEvenetListener est la raison principale pour laquelle j'ai créé le tableau afin que je puisse ajouter toutes les données mises à jour dans le tableau. Existe-t-il un moyen pour que les données mises à jour soient ajoutées dans le tableau et lorsque le tableau est appelé de n'importe où dans la classe, il affiche réellement les données?


`les données mises à jour sont ajoutées dans le tableau`: Vous ajoutez correctement des données à votre arraylist. Maintenant, quand vous l'utilisez. vérifier si arraylist n'est pas vide puis l'utiliser


c'est le problème. J'ai en fait besoin qu'il ne soit pas vide à un moment donné.


puis ajoutez-y d'abord des valeurs, puis utilisez-le.


Je veux que les données de addValueEventListener soient ajoutées au tableau. Et puis à partir d'une autre méthode, je dois utiliser le tableau pour ajouter des marqueurs à une carte. Mais quand je fais cela, une erreur indique que le tableau est vide.


alors vous devez changer la séquence d'exécution du code. Vous devez écrire le code addValueEventListener avant cette méthode.


avant la méthode onCreate?


non avant onCreate cela provoquera une erreur. utiliser avant cette méthode, vous utilisez cette arraylist dans


addEventValueListener est dans la méthode onCreate et il est avant la méthode qui tente d'utiliser le tableau.


afficher la méthode dans laquelle vous essayez d'accéder à cette liste


Je l'ai mis dans mon code de questions. C'est tout en bas. Il s'appelle onMapReady ().


Je ne comprends pas votre cas d'utilisation en détail (je ne sais pas ce qu'est une `` firebase ''), mais cela semble se résumer à ceci: (a) ajoutez les données quand elles sont disponibles pour la première fois, et (b) don 'pas effacer la liste.


@ Another-Dave, j'ai fait de mon mieux pour résoudre son problème. mais sans code et sans flux, je ne peux pas faire grand chose


J'ai mis à jour le code dans mes questions. Pouvez-vous s'il vous plaît y jeter un œil et me suggérer une solution? Merci!


@NeelPatel afin que vous souhaitiez générer une notification lorsque onDataChange est appelé?


Je le veux donc lorsque j'appelle la taille du tableau à partir de la méthode principale, elle montre en fait la taille correcte.


@NeelPatel continuons la discussion dans la salle de chat