Issue
I have a problem with AsyncTask
, onPostExecute
method runs before doInBackground
method finishes its job.
I'm trying to get some data from Firebase database, save it to an array list of "Didattica" objects to be passed to an expandable list view, I have 4 object on the database.
The problem is that onPostExecute
runs soon after doInBackground
and then doInBackground
finishes its job populating the arrayList.
public class DidatticaActivity extends AppCompatActivity {
ArrayList<Didattica> reishiki1 = null;
private ExpandableListView listView1;
private ExpandableListAdapter listAdapter1;
private List<String> listDataHeader1;
private HashMap<String, List<String>> listHash1;
AsyncTaskDidattica atDidattica;
final FirebaseDatabase database = FirebaseDatabase.getInstance();
private DatabaseReference refDidattica1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_didattica);
listHash1 = new HashMap<>();
listDataHeader1 = new ArrayList<>();
listView1 = findViewById(R.id.lvReishiki);
atDidattica = new AsyncTaskDidattica();
atDidattica.execute();
listAdapter1 = new ExpandableListAdapter(this, listDataHeader1,listHash1);
listView1.setAdapter(listAdapter1);
}
private class AsyncTaskDidattica extends AsyncTask<String, String, HashMap<String, ArrayList<Didattica>>>{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected HashMap<String, ArrayList<Didattica>> doInBackground(String... strings) {
HashMap result = new HashMap<>();
reishiki1 = new ArrayList<>();
try {
refDidattica1 = database.getReference("didattica/1-reishiki");
refDidattica1.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot1) {
Log.i("shinseiLog", "onDataChange" );
for (DataSnapshot child1 : dataSnapshot1.getChildren()) {
Didattica d1 = child1.getValue(Didattica.class);
reishiki1.add(d1);
}
Log.i("shinseiLog", "rei size1: " + reishiki1.size());
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
result.put("reishiki", reishiki1);
Log.i("shinseiLog", "map size 1: " + result.size());
return result;
}catch(Exception e){
Log.i("shinseiLog", "eccezione in doInBackground");
}
return null;
}
@Override
protected void onPostExecute(HashMap<String, ArrayList<Didattica>> result) {
super.onPostExecute(result);
ArrayList<Didattica> rei = result.get("reishiki");
Log.i("shinseiLog", "rei size2: " + rei.size());
for(Didattica r: rei){
listDataHeader1.add(r.getTitolo());
listHash1.put(r.getTitolo(),r.getList());
}
Log.i("shinseiLog", "header: " + listDataHeader1.size());
Log.i("shinseiLog", "hash: " + listHash1.size());
listAdapter1.notifyDataSetChanged();
}
}
}
I added some logs to help understand the order:
I/shinseiLog: map size 1: 1
I/shinseiLog: rei size2: 0
I/shinseiLog: header: 0
I/shinseiLog: hash: 0
I/shinseiLog: onDataChange
I/shinseiLog: rei size1: 4
Last row correctly shows that the arrayList contains all my data, but it is too late. Why is it executing this way? Where am I wrong?
Thanks
Solution
Remember that firebase is async. So your method...
public void onDataChange(DataSnapshot dataSnapshot1) {
}
...is executing in another thread. That's why onPostExecute
is executed first.
Try this, put the code from onPostexecute
code inside the method onDataChange
, see this picture
Answered By - edison gudiño
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.