[英]Prevent android app crash when callable firebase function throws exception
[英]App crash with GC When an object added to firebase - Android Studio
您好,我有一个 Android 应用程序
当在 firebase 中完成更新(在 firebase 中插入新数据或更新属性)时,应用程序将崩溃 15-30 秒。
当我检查日志时,它表明当时 GC 正在工作,并且需要花费大量时间来完成他的工作,因此该应用程序崩溃了很多时间,并且在电话上,您无法执行任何操作,直到 GC 在那里完成工作,我的数据库中没有太多数据,我的应用程序也没有那么大。
您可以在此处查看日志:
I/lhindeliveryma: Background concurrent copying GC freed 325485(8953KB) AllocSpace objects, 0(0B) LOS objects, 36% free, 10MB/16MB, paused 218us total 136.046ms
W/Looper: Slow Looper main: Long Msg: seq=1424 plan=02:06:39.877 late=2ms wall=2060ms running=1848ms runnable=39ms io=29ms h=android.os.Handler c=com.google.firebase.database.core.view.EventRaiser$1
I/lhindeliveryma: Background concurrent copying GC freed 373886(10MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 11MB/17MB, paused 259us total 155.904ms
I/lhindeliveryma: Background concurrent copying GC freed 501873(13MB) AllocSpace objects, 0(0B) LOS objects, 33% free, 11MB/17MB, paused 394us total 247.891ms
I/lhindeliveryma: Background young concurrent copying GC freed 323701(8831KB) AllocSpace objects, 0(0B) LOS objects, 31% free, 12MB/17MB, paused 537us total 116.240ms
I/lhindeliveryma: Background concurrent copying GC freed 567601(15MB) AllocSpace objects, 0(0B) LOS objects, 32% free, 12MB/18MB, paused 430us total 288.562ms
I/lhindeliveryma: Background young concurrent copying GC freed 351662(9586KB) AllocSpace objects, 0(0B) LOS objects, 32% free, 12MB/18MB, paused 528us total 125.947ms
W/Looper: Slow Looper main: Long Msg: seq=1425 plan=02:06:40.037 late=1902ms wall=1811ms running=1692ms runnable=2ms h=android.os.Handler c=com.google.firebase.database.core.view.EventRaiser$1
I/Choreographer: Skipped 180 frames! The application may be doing too much work on its main thread.
这就是日志所说的
这是我如何从 firebase 接收数据的代码:
FirebaseAuth mAuth;
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
firebaseDatabase = FirebaseDatabase.getInstance();
EndLoop:
databaseReference = firebaseDatabase.getReference().child("Orders").child(City);
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
You = new ArrayList<>();
Now = new ArrayList<>();
postAd = new OrderAD();
boolean stop = false;
for (DataSnapshot postsnap : dataSnapshot.getChildren()) {
if(!stop)
for (DataSnapshot postsnap1 : postsnap.getChildren()) {
if(!stop)
for (DataSnapshot postsnap2 : postsnap1.getChildren()) {
if (!stop) {
Order post = postsnap2.getValue(Order.class);
if (!post.getStatus().equals("تم التوصيل") && !post.getStatus().equals("تم الغاء الطلب")) {
if (post.getDeliveryUID().equals(user.getUid()))
You.add(post);
else {
if (post.getDeliveryUID().equals("")) {
Now.add(post);
}
}
if (!Offers.contains(post.getKey())) {
Offers.add(post.getKey());
if (Done) {
show_Notification(post);
You.clear();
Now.clear();
stop = true;
System.out.println("Hello");
break;
}
}
}
break;
}
}
}
}
if(!Done){
Done = true;
}
Collections.sort(Now);
Collections.sort(You);
postAd = new OrderAD(Offers.this, Now);
recyclerView.setAdapter(postAd);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
有什么建议可以解决这个问题吗?
应用程序将崩溃。
这是预期的行为,因为一次读取 1000 多个节点可以被视为大量数据,这很可能不适合 memory。 除此之外,我看到你循环了孩子们三遍。 这意味着在Orders/City
下还存在其他节点,这意味着要读取更多数据。 在实时数据库中,当您将侦听器附加到数据库中的特定位置时,您会读取(下载)该节点及其下的所有子节点。 在这种情况下,最好对数据进行非规范化。 这意味着您应该创建另一个节点,该节点应该只包含您对节点的平面列表感兴趣的数据。 除此之外,最好根据您的需要通过调用Query#limitToFirst(int limit)或Query#limitToLast(int limit)来限制您读取的数据量。 除此之外,还建议实现pagination 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.