I'm having an issue when trying to update multiple paths after looping through the queries.
Here's a quick mock up of my database:
Subjects/
- subjectId/
- subjectName
- subjectColor
Tasks/
- taskId/
- taskTitle
- taskDesc
- subjectId
- subjectName
- subjectColor
SubjectTasks/
- taskId/
- taskTitle
- taskDesc
- subjectId
- subjectName
- subjectColor
I have an activity in my app where users can edit the subjects' name and color. In order to update the subjectName
and subjectColor
properties of tasks with a subjectId
value matching the one we edited I need to do a whole bunch of querying and looping through the Tasks
and subjectTasks
nodes. This is where the major performance hit happens (I think!)
It's this heavy looping and writing operation which I believe causes garbage collection to trigger, halting all threads, sending my app into an indeterminate loading screen.
Garbage collection triggered when subject is edited and saved :(
After many hours studying the heap and the memory profiler in Android Studio I have no other ideas other than posting here. It's more annoying that this was found just days before release!
Here is the code snippet of the activity where the writing of the edited subject happens:
private void WriteEditedSubject(final String uid, final String subjectName, final String primaryColour, int swatchId){
final DatabaseReference rootRef = mDatabase.getRef();
SubjectItem editedSubject = new SubjectItem(subjectName, primaryColour, swatchId);
editedSubject.setUid(subjectId);
//create map of edited values
Map<String, Object> subjectValues = editedSubject.toMap();
//create map of updates to push
final Map<String, Object> subjectUpdates = new HashMap<>();
//update subjects node
subjectUpdates.put("/subjects/" + uid + "/" + subjectId, subjectValues);
//push updates
rootRef.updateChildren(subjectUpdates);
//todo: run a cloud function to update subject tasks and subjects using data from updated subject
//update subject tasks node where tasks match subjectId
mSubjectTasks.orderByChild("subjectId").equalTo(subjectId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//create map of updates to push
Map<String, Object> subjectTaskUpdates = new HashMap<>();
for(DataSnapshot taskShot : dataSnapshot.getChildren()){
TaskItem task = taskShot.getValue(TaskItem.class);
if(task != null) {
task.setSubjectName(subjectName);
task.setSubjectPrimaryColour(primaryColour);
Map<String, Object> taskValues = task.toMap();
subjectTaskUpdates.put("subjectTasks/" + uid + "/" + subjectId + "/" + task.getUid(), taskValues);
}
}
rootRef.updateChildren(subjectTaskUpdates);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
//update tasks node where tasks match subjectId
mTasks.orderByChild("subjectId").equalTo(subjectId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//create map of updates to push
Map<String, Object> taskUpdates = new HashMap<>();
for(DataSnapshot taskShot : dataSnapshot.getChildren()){
TaskItem task = taskShot.getValue(TaskItem.class);
if(task != null) {
task.setSubjectName(subjectName);
task.setSubjectPrimaryColour(primaryColour);
Map<String, Object> taskValues = task.toMap();
taskUpdates.put("tasks/" + uid + "/" + task.getUid(), taskValues);
}
}
rootRef.updateChildren(taskUpdates);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Is there a way this operation can be cleaned up and made more efficient? One idea I had was to write a cloud function that would trigger when the subject is edited but I'm determined to find out why this is happening.
Thanks for any help. Much appreciated!
It looks like what Bob Snyder pointed out was correct.
Replacing AddValueEventListener
with AddListenerForSingleEvent
fixed the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.