如何在 OnDestroy 中删除此 firebase 侦听器以减少内存泄漏?

Posted

技术标签:

【中文标题】如何在 OnDestroy 中删除此 firebase 侦听器以减少内存泄漏?【英文标题】:How do I remove this firebase listener in OnDestroy to reduce memory leaks? 【发布时间】:2021-12-07 01:49:35 【问题描述】:

这是我的产品展示功能。当我从另一个活动访问此活动时,另一个活动可能由于内存泄漏而被破坏。我该如何解决这个问题?如何关闭听众?我想销毁这是 OnDestroy 方法,因为它可能会导致内存泄漏,而且我已经读到这样做是一个好习惯。

private void getProductDetails(String productID) 
        DatabaseReference productsRef = FirebaseDatabase.getInstance().getReference().child("Products");
        productsRef.child(productID).addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NotNull DataSnapshot dataSnapshot) 
                if (dataSnapshot.exists())
                    Products products = dataSnapshot.getValue(Products.class);
                    productName.setText(products.getPname());
                    productPrice.setText(products.getPrice());
                    if (products.getInStock().equals("Yes"))
                        inStock.setText("In Stock");
                        inStock.setTextColor(ContextCompat.getColor(ProductDetailsActivity.this,R.color.primary));
                    else 
                        inStock.setText("Not In Stock");
                        inStock.setTextColor(ContextCompat.getColor(ProductDetailsActivity.this,R.color.red));
                        addToCartBtn.setEnabled(false);
                    
                    ifFreeDelivery = "No";
                    DatabaseReference mref;
                    final String[] phone = new String[1];
                    mref = FirebaseDatabase.getInstance().getReference("Values").child("deliveryCharge");
                    mref.addListenerForSingleValueEvent(new ValueEventListener() 
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) 
                            phone[0] = dataSnapshot.getValue(String.class);
                            deliveryCharge = Integer.parseInt(phone[0]);
                            //do what you want with the likes
                        

                        @Override
                        public void onCancelled(DatabaseError databaseError) 

                        
                    );


                    Products productsImg = dataSnapshot.getValue(Products.class);
                    ArrayList<String> test = productsImg.getImage();
                    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
                    DatabaseReference myRef = rootRef.child("Products").child(products.getPid()).child("image");
                    myRef.addChildEventListener(new ChildEventListener() 
                        @Override
                        public void onChildAdded(DataSnapshot dataSnapshot, String s) 
                            //this will be called for every child in your list
                            test.add(s);
                        

                        @Override
                        public void onChildChanged(DataSnapshot dataSnapshot, String s) 
                            //this will be called for every child changed in your list
                        

                        @Override
                        public void onChildRemoved(DataSnapshot dataSnapshot) 

                        

                        @Override
                        public void onChildMoved(DataSnapshot dataSnapshot, String s) 

                        

                        @Override
                        public void onCancelled(DatabaseError databaseError) 

                        

                    );
                    ArrayList<SlideModel> images = new ArrayList<>();
                    for(int i = 0; i < test.size() ; i++) 
                        images.add(new SlideModel(test.get(i),null));

                    
                    productImage.setImageList(images);
                    productImgDownloadBtn.setOnClickListener(v -> 
                        for(int i = 0; i < products.getPicCount() ; i++) 
                            String url = test.get(i).replace(" ","");
                            DownloadImage(url);



                        
                    );


                    productDescription.setText(products.getDescription());
                    productDetailsCopyBtn.setOnClickListener(new View.OnClickListener() 
                        @Override
                        public void onClick(View view) 
                            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                            ClipData clip = ClipData.newPlainText("Product description",products.getDescription());
                            clipboard.setPrimaryClip(clip);
                            Toast.makeText(ProductDetailsActivity.this, "Product description copied..", Toast.LENGTH_SHORT).show();
                        
                    );
                    //Picasso.get().load(products.getImage().get(0)).into(productImage);
                
            


            @Override
            public void onCancelled(@NonNull @NotNull DatabaseError databaseError) 

            

        );
        

    

【问题讨论】:

【参考方案1】:

正如我在您的代码中看到的,您在第一部分中使用了addValueEventListener(),这意味着您正在侦听实时更新。那种听众should be removed according to the life cycle of your activity。另请注意,onDestroy is not always called.

但是,当使用addListenerForSingleValueEvent()时,不需要移除任何监听器,因为它只读取一次数据。

【讨论】:

嘿 ucchasharen。我可以帮助您了解其他信息吗?如果您认为我的回答对您有所帮助,请考虑通过单击左侧投票箭头下方的复选标记(✔️)来接受它。应将颜色更改为绿色。我真的很感激。谢谢!

以上是关于如何在 OnDestroy 中删除此 firebase 侦听器以减少内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

使用共享首选项保存和重新加载 ListView [保存 onDestroy()]

如何防止 onPause() 之后调用 onDestroy()?

如何在 Delphi 的 TFrame 上模拟 OnDestroy 事件?

如何在 Android 中服务 onDestroy 后保持对象变量处于活动状态?

在 onDestroy 中进行所有清理是不是安全?

Android,从“最近的应用”中删除应用时取消通知