2017-10-06 2 views
0

Ich habe eine TextView in meiner Aktivität - sagen wir, "Benutzername". Es soll von einer Firebase-Datenbank gefüllt werden. Ich mache die Firebase-Abfrage in Asynctask, um die Aktivität nicht zu blockieren. Das bedeutet jedoch, dass TextView zuerst geladen wird, bevor die Firebase-Abfrage vollständig ausgeführt wird.Androide Textansicht zu Firebase Datenbankfeld

Also, was ist der beste Weg, diese TextBox zu aktualisieren, nachdem die Firebase-Abfrage innerhalb der AsyncTask ausgeführt wird und der Benutzername bekannt wird? Ich möchte ProgressBar nicht anzeigen und die Aktivität blockieren, während die Daten aus der Datenbank abgerufen werden. Das würde den Zweck, es in AsyncTask zu tun, vereiteln.

-Code für die AsyncTask unten ist

private class CheckUserLoginAndRetrieveDataFromFirebase extends AsyncTask <Void, Void, Void> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 


    @Override 
    protected Void doInBackground(Void... voids) { 
     if (thisAppUser!=null) { 
      setUserDataForToday(); 
      if (createNewNode) { //This is the first time the User is logging in 
       createUsersNodesForFirstTime(); 
      } 
     } 
     return null; 
    } 

-Code für meine Firebase Abfrage im AsyncTask unter

public static void setUserDataForToday() { 
    setProperDatabaseReference(); //This sets reference to user specific nodes in the database 
    myRef.child("dashboard").addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      Dashboard dashboard = dataSnapshot.getValue(Dashboard.class); 
      if (dataSnapshot.getChildrenCount() > 0) { 
       createNewNode = false; 
       if (dashboard.checkIfTodaysDateExistsInDatabase()) { 
        //An entry for todays date exists in database, so no data change needed 
        myDashboard = dashboard; 
       } 
+1

Die Firebase Datenbank-Client bereits alle Netzwerk-Interaktion ausgeführt wird, besteht keine Notwendigkeit, eine 'AsyncTask' dafür zu verwenden. Anschließend ruft es Ihren 'onDataChange' im Hauptthread auf, sodass Sie die Benutzeroberfläche aktualisieren können. –

+0

@ FrankvanPuffelen- Hallo Frank, ja, ich verstehe und versuchte es früher, aber ich bekomme immer wieder Probleme mit statischen und nicht statischen Variablen und Methoden. Auch der "Kontext" der Aktivität ist in "onDataChange" nicht verfügbar. Ich möchte den Benutzer nicht davon abhalten, sich von der Aktivität, die den Benutzernamen abruft, weg zu bewegen, damit ich den Kontext oder die UI-Elemente nicht behalten möchte. Aber für den Fall, dass er noch aktiv ist, wenn der "onDataChange" beendet ist, möchte ich das entsprechende UI-Element aktualisieren. Was würden Sie am effizientesten dafür vorschlagen? –

Antwort

2

Ich hoffe, dass dieses Beispiel wird Ihnen helfen, aus dem Haupt-Thread

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     setUserDataForToday(); 
     Log.d("MainActivity", "Process is not blocked"); 
    } 

    public void setUserDataForToday() { 
     Log.d("MainActivity", "Called method"); 
     DatabaseReference database = FirebaseDatabase.getInstance().getReference(); 
     database.child("users").child("1").child("name").addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       if (dataSnapshot.exists()) { 
        String userName = dataSnapshot.getValue(String.class); 
        Log.d("MainActivity", "Received value: " + dataSnapshot.getValue()); 
        dataSnapshot.getKey(); 
        TextView textView = (TextView) findViewById(R.id.textUserName); 
        textView.setText(userName); 
       } 
      } 
      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       Log.d("MainActivity", "DB error: " + databaseError.getMessage()); 
      } 
     }); 
    } 

    public void onClick(View v) { 
     setUserDataForToday(); 
    } 
} 
+0

Dies funktioniert nicht, da onPostExecute viel schneller aufgerufen wird, als die Daten vom Firebase –

+0

abgerufen werden. Sie haben Recht. Der Firebase-Client lädt die Daten in einem separaten Thread. Also wartet AsyncTask nicht. Aus welchem ​​Grund haben Sie setUserDataForToday() static gemacht? Sie können nicht statische Eigenschaften nicht von der statischen Methode aufrufen, sodass Sie die Benutzeroberfläche nicht ändern können. Wenn Sie setUserDataForToday() nicht statisch machen, können Sie es aus dem Hauptthread aufrufen und TextView in der Methode onDataChange (DataSnapshot dataSnapshot) ändern. –

+0

Ich habe es statisch gemacht, weil ich die gleiche Funktion für eine andere Aktivität wiederverwenden muss. Anstatt es also erneut zu schreiben, habe ich es in einer separaten Klasse statisch gemacht. –

0

Wenn Sie mit Android Studio Click-Tool arbeiten> Firebase> Echtzeit-Datenbank und folgen Anleitung. Dies wird Ihnen helfen. Sie möchten wahrscheinlich auf Tools> Firebase> Authentifizierung klicken, wenn Sie Benutzer haben möchten und wenn nur bestimmte Benutzer auf bestimmte Dinge zugreifen möchten, konfigurieren Sie Regeln für die Datenbank. Frank hat keine asynchrone Aufgabe nötig.

Verwandte Themen