2017-10-06 70 views
0

我有一個textView在我的活動 - 比如說,「用戶名」。它應該從Firebase數據庫填充。我正在Asynctask中進行Firebase查詢,以免阻止活動。但是,這意味着在Firebase查詢完全執行之前,TextView會首先加載。將android textview綁定到firebase數據庫字段

那麼在Firebase查詢在AsyncTask內部執行並且知道用戶名後刷新此文本框的最佳方式是什麼? 我不想在數據從數據庫中獲取數據時顯示progresspath並阻止活動。這將在AsyncTask中失敗。

代碼爲的AsyncTask低於中的AsyncTask

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

代碼爲我的火力地堡查詢低於

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

的火力地堡數據庫客戶端使用主線程中的所有網絡互動已經,沒有必要使用一個'AsyncTask'了點。然後它在主線程上調用你的'onDataChange',這樣你就可以更新UI。 –

+0

@ FrankvanPuffelen-嗨,弗蘭克,是的,我理解並早些時候嘗試過,但我不斷收到有關靜態和非靜態變量和方法的問題。此外,該活動的「上下文」在「onDataChange」中不可用。我不想阻止用戶從正在檢索「用戶名」的活動中導航,所以我不想保留上下文或用戶界面元素。但是,如果他在「onDataChange」完成時仍處於該活動狀態,我想刷新適當的UI元素。你認爲最有效的方法是什麼? –

回答

2

我希望這個例子可以幫助你

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

由於onPostExecute被調用的速度比從Firebase檢索數據要快得多,因此這不起作用 –

+0

您是對的。 Firebase客戶端將數據加載到單獨的線程中。所以AsyncTask不會等待它。你是什​​麼原因使setUserDataForToday()是靜態的?你不能從靜態方法調用非靜態屬性,所以你不能改變UI。如果您將setUserDataForToday()設置爲非靜態,則可以從主線程調用它並更改onDataChange(DataSnapshot dataSnapshot)方法中的TextView。 –

+0

我將其設爲靜態,因爲我需要爲其他活動重複使用相同的功能。所以我沒有再寫一遍,而是在一個單獨的課堂上把它變成靜態的。 –

0

如果您正在使用的Android工作室點擊工具工作>火力地堡>實時數據庫,並按照說明。這會讓你開始。如果您想擁有用戶,並且只希望某些用戶訪問某些內容,爲數據庫配置規則,則可能需要單擊工具> Firebase>身份驗證。弗蘭克是正確的,不需要異步任務。

相關問題