Reputation: 95
I'm developing an Android+Firebase app but since I'm new to both techlogies I'm having a problem regarding async calls and I haven't found the solution yet so hope you can help me.
I have the following snippet in my Activity's onCreate
method:
final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();
DatabaseReference assetsLocationReference = database.getReference(FirebaseReferences.ASSETSLOCATION_REFERENCE);
assetsLocationReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
ArrayList<String> assetsLocationSpinner = new ArrayList<String>();
// Create an ArrayAdapter using the string array and a default spinner layout
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
//Getting the data from snapshot
AssetLocation assetsLocation = postSnapshot.getValue(AssetLocation.class);
assetsLocations.add(AssetLocation);
}
}
@Override
public void onCancelled(DatabaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
I also have a pretty similar call but instead of getting Locations, I'm getting Types.
After this code (inside the onCreate method as well), I'm calling setScreenInfo
which is a function to fill both spinners (and do more stuff) with said data but since it is an async call, the spinners are blank when I execute it.
How can I execute setScreenInfo
once the calls are made? I tried with .once()/.on()
but it's not being recognised by Android Studio as a function.
Thanks for your help!
Upvotes: 0
Views: 553
Reputation:
You can use thread:
thread = new Thread() {
@Override
public void run() {
try {
//background tasks
runOnUiThread(new Runnable() {
@Override
public void run() {
//UI tasks
}
});
}
catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();`
Or you can use Firebase Multi Query method. link: Only load layout when firebase calls are complete
Upvotes: 0
Reputation: 138834
Because of the asynchronously behaviour, you need to move the declaration of the assetsLocations
ArrayList:
final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();
inside the onDataChange()
method, as assetsLocationSpinner
ArrayList is. So remember, onDataChange
is always called asynchronously
. This means that the statement that adds objects of AssetLocation
class to the list is executed before onDataChange
has been called. That's why your list is empty outside that method.
For other approach, please visit this post and this post.
Hope ot helps.
Upvotes: 0
Reputation: 2380
After this code (inside the onCreate method as well), I'm calling setScreenInfo which is a function to fill both spinners (and do more stuff) with said data but since it is an async call, the spinners are blank when I execute it.
You aren't allowed to modify the UI from a background thread. Normally I would make a call to runOnUIThread
, passing a new Runnable() and a final
copy of the data I want to pass.
final String myData = "updateData";
ActivityName.this.runOnUiThread(new Runnable() {
public void run() {
// use myData to update UI
}
});
However, it seems like there's a migration to AsyncTask
: Converting runOnUiThread to AsyncTask
I personally still use runOnUIThread
. It's more explicit.
Upvotes: 1