2017-01-13 26 views
1

我正在使用Firebase作为数据库开发Android Studio中的应用程序,并且我有一个棘手的问题。我有一个从辅助类中获取'pregunta'对象的片段,我在其中对数据库执行实际查询。问题是侦听器启动一个单独的线程来等待事件,但同时该方法继续处理并返回一个空值。Firebase数据库和Android:使用Firebase类不同于活动/片段类

任何想法如何避免这种异步或更好的方式来实现呢?谢谢!!

片段类:

mPregunta = mSesionManager.getPregunta(id_pregunta_actual); 
    TextView view_pregunta = (TextView)view.findViewById(R.id.titulo_pregunta); 
    view_pregunta.setText(mPregunta.getTxt_pregutna()); 

辅助类方法:

public pregunta getPregunta(long id){ 
    mp.setId_pregunta(id); 

    Query query = mDB_Cuestionario.child("Tabla_Preguntas").orderByChild("id").equalTo(id); 
    query.addChildEventListener(new ChildEventListener() { 
     @Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
      mp.setTxt_pregutna(dataSnapshot.child("txt").getValue().toString()); 
      Log.e("FBHELPER", "ID LISTENER: "+mp.getId_pregunta()); 
      Log.e("FBHELPER", "TXT LISTENER: "+mp.getTxt_pregutna()); 
     } 

     [-- rest of code --] 
    }); 

    Log.e("FBHELPER", "TXT RESPUESTA: "+mp.getTxt_pregutna()); 
    return mp; 
} 

日志:

The method returns null value: 
    01-13 17:16:52.101 8994-8994/com.example.fran.cuestionario E/FBHELPER: TXT RESPUESTA: null 

1 second later, the Event occurs, but I can't return the value. 
    01-13 17:16:53.497 8994-8994/com.example.fran.cuestionario E/FBHELPER: ID LISTENER: 0 
    01-13 17:16:53.497 8994-8994/com.example.fran.cuestionario E/FBHELPER: TXT LISTENER: TEST VALUE 
+0

你可以'公共pregunta getPregunta(长ID,ChildEventListener听众){// .. query.addChildEventListener(监听); // ..}'然后更新你的片段类 – Linxy

回答

0

你不能这样做的。 Firebase侦听器是异步的,因此它将在Firebase加载数据之前返回。

我也试过,没有办法很容易完成它。但是,当应用程序启动时,您可以预先加载所有数据,并将其保存在散列图或ArrayList等中。然后,您可以轻松地在活动中检索列表以及所有这些碎片。

这就是我这样做的方式,它完美地运作。如果你想知道更多关于它的信息,告诉我。

+0

感谢Hhorn的回答,我相信这可以在某些场景下工作。不过,我实际上正在测试Firebase的非SQL数据库,并认为基于其他非关键属性来选择元素会更容易,但使用HashMaps或Arrays会使这变得复杂......我会看一看如果我能够很好地做到这一点。 –

1

当您向Firebase注册侦听器时,发生注册时不会阻塞正在运行的线程。听众正在做的事情是:“当数据中的某些东西变得可用时,让我知道 - 我知道这不会马上发生,但一段时间后会发生。”

您必须围绕这些听众的工作方式来设计您的应用程序。您必须对来自侦听器的传入信息做出反应,而不是阻止其上的任何线程。

+0

我已将代码从辅助类移动到片段类,至少应用程序显示从数据库获取的内容。然而,从用户的角度来看,它并不是最佳的,因为片段正在等待(或侦听)Firebase,然后填充TextView而不是直接实际获取数据,所以会出现“眨眼”。任何有关如何获得更流畅的可视化的想法? –

+0

在等待结果时显示微调或某个过渡视图。 –

1

我最终做的是基于Hhorn使用ArrayLists的建议。因为我需要根据参数选择不同的元素,所以我只做了一个基本的搜索算法方法,它返回另一个数组,我可以将它传递给适配器以在屏幕上显示它。

负载

@Override 
      public void onChildAdded(DataSnapshot dataSnapshot, String s) { 

       respuesta r = new respuesta(
         Integer.valueOf(dataSnapshot.child("id_po").getValue().toString()) 
         , String.valueOf(dataSnapshot.child("txt").getValue().toString()) 
         ); 
       mSesionManager.mArrayRespuestas.add(r); 

      } 

搜索:

public ArrayList<respuesta> queryRespuestasFB(long id_pregunta_origen){ 
     ArrayList<respuesta> respuestas_seleccionadas = new ArrayList<respuesta>(); 

     for(respuesta r : mArrayRespuestas){ 
      if (r.getId_pregunta_origen()==id_pregunta_origen){ 
       respuestas_seleccionadas.add(r); 
       //Log.e("SM", "Respuesta Query: "+ r.toString()); 
      } 
     } 

     return respuestas_seleccionadas; 
    }