我知道这个问题可能看似重复,我已经读过十条关于同样事情的其他帖子,但我找不到问题
我的活动中有这个方法:
public void saveResponse(final Response studentResponse, final Content content)
fb.getReference("...").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
new Thread(new Runnable() {
@Override
public void run() {
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("end_date", studentResponse.end_date);
responseMap.put("start_date", studentResponse.start_date);
responseMap.put("time", studentResponse.time);
responseMap.put("points", studentResponse.points);
responseMap.put("max_points", studentResponse.max_points);
responseMap.put("selected_options", studentResponse.selected_options);
if (!TextUtils.isEmpty(studentResponse.free_text))
responseMap.put("free_text", studentResponse.free_text);
DataSnapshot contentRef = dataSnapshot.child("/sections/" + currentSection + "/sections/" + currentSubsection + "/contents/" + content.id);
final int oldPoints = contentRef.hasChild("points") ? contentRef.child("points").getValue(int.class) : 0;
contentRef.getRef().setValue(responseMap);
contentRef.getRef().setPriority(ServerValue.TIMESTAMP);
DataSnapshot subSectionRef = dataSnapshot.child("/sections/" + currentSection + "/sections/" + currentSubsection);
long subSectionPoints = (subSectionRef.hasChild("points") ? subSectionRef.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
subSectionRef.child("points").getRef().setValue(subSectionPoints);
int indexOf = currentContents.indexOf(content) + 1;
if(indexOf > 0 && indexOf < currentContents.size()) {
CourseContent content = currentContents.get(indexOf);
subSectionRef.child("currentPosition").getRef().setValue(content.order);
}
DataSnapshot sectionRef = dataSnapshot.child("/sections/" + currentSection);
long sectionPoints = (sectionRef.hasChild("points") ? sectionRef.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
sectionRef.child("points").getRef().setValue(sectionPoints);
long coursePoints = (dataSnapshot.hasChild("points") ? dataSnapshot.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
dataSnapshot.child("points").getRef().setValue(coursePoints);
dataSnapshot.getRef().setPriority(MAX_SAFE_INTEGER - coursePoints);
int completed = 0;
for (DataSnapshot sect : dataSnapshot.child("sections").getChildren()) {
for (DataSnapshot subSect : sect.child("sections").getChildren()) {
int currPos = subSect.hasChild("currentPosition") ? subSect.child("currentPosition").getValue(int.class) : 0;
completed += currPos;
}
}
double progress = totalContents > 0 ? (double) completed / (double) totalContents : 0;
dataSnapshot.child("progress").getRef().setValue(progress);
}
}.start();
}
...
});
}
单击处理程序中的我调用此方法,然后更改片段(使用自定义动画)。
问题是,片段转换不顺畅,它会冻结一点,如果我在runnable中评论所有内容,那么它会顺利运行。我也尝试过AsyncTask,同样的事情发生了。
在runnable中,我只是查询dataSnapshot及其子节点,并设置一些值(dataSnapshot.child("item").getRef().setValue(x)
)
另一个奇怪的事情是,如果我在run()中放置一个断点,它也可以顺利运行。
答案 0 :(得分:0)
我认为问题在于你的方法的逻辑。
侦听器onDataChange()处于活动状态,它将响应数据的任何更改。我的意思是如果您更改onDataChange()方法中的数据,每次使用(dataSnapshot.child(&#34; item&#34;)。getRef()。setValue(x)))设置值时都会调用它,所以,它类似于做一个&#34;递归&#34;打电话没有退出。
为了解决此问题,您应该在点击事件中获取要更改的内容的密钥,然后使用
mDatabase = FirebaseDatabase.getInstance()。getReference(); mDatabase.child(&#34;键&#34)。子(&#34;项目&#34)。的setValue(X);
查看https://firebase.google.com/docs/database/android/read-and-write了解详情
答案 1 :(得分:0)
生成的线程继承创建它的线程的优先级。尝试降低工作线程的优先级,以防止它与UI线程竞争:
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
new Thread(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
...
}).start();
答案 2 :(得分:0)