简体   繁体   English

Firebase 快照侦听器:在活动被破坏时滑动非法参数异常 (Java)

[英]Firebase Snapshot Listener: Glide Illegal Argument Exception on Activity Destroyed (Java)

I'm using firebase snapshot listener on my adapter.我在我的适配器上使用 firebase 快照侦听器。 And, whenever the value updates the adapter is updated.并且,每当值更新时,适配器就会更新。 But the problem is it tries to update even when the activity is destroyed.但问题是即使活动被破坏,它也会尝试更新。
It is crashing at Glide.with(holder.itemView.getContext()) and the error is You cannot start a load for a destroyed activity它在Glide.with(holder.itemView.getContext())处崩溃,错误是您无法为已销毁的活动启动加载

Yes, there are lots of related questions on stackoverflow.是的,stackoverflow 上有很多相关的问题。 Must of them aren't possible in adapter.它们中的必须在适配器中是不可能的。 I also tried recyclerView.setAdapter(null) , recyclerView.removeAllViewsInLayout() on my fragment but none is working.我也在我的片段上尝试过recyclerView.setAdapter(null)recyclerView.removeAllViewsInLayout() ,但都没有工作。

Simplified adapter Code简化的适配器代码

 @Override
protected void onBindViewHolder(@NonNull final ChatHolder holder, int position, @NonNull final MessageClass model) {

    final FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();


    firebaseFirestore.collection("users").document(model.getUser_receiver())
            .addSnapshotListener(new EventListener<DocumentSnapshot>() {
                @Override
                public void onEvent(@Nullable DocumentSnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
                    if (queryDocumentSnapshots != null) {

                            ProfileClass profileClass = queryDocumentSnapshots.toObject(ProfileClass.class);
                                 String userId = queryDocumentSnapshots.getString("user_uid");

                            if(userId != null) {

                                    if (profileClass.getUser_image().equals("image")) {
                                        Glide.with(holder.itemView.getContext()).load(R.drawable.profile_image).into(holder.roundedImageViewChatsItemChatsImage);

                                    } else {
                                        Glide.with(holder.itemView.getContext()).load(profileClass.getUser_image()).into(holder.roundedImageViewChatsItemChatsImage);

                                    }
                                }
                                }

                        }

            });

Logs日志

Java.lang.IllegalArgumentException: 
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed 
 (RequestManagerRetriever.java:323)
 at com.bumptech.glide.manager.RequestManagerRetriever.get (RequestManagerRetriever.java:132)
 at com.bumptech.glide.manager.RequestManagerRetriever.get (RequestManagerRetriever.java:116)
 at com.bumptech.glide.Glide.with (Glide.java:707)
 at com.meeti.all.Chats.ChatsFirestore$1.onEvent (ChatsFirestore.java:111)
 at com.meeti.all.Chats.ChatsFirestore$1.onEvent (ChatsFirestore.java:64)
 at com.google.firebase.firestore.DocumentReference.zza (SourceFile:497)
 at com.google.firebase.firestore.zzd.onEvent (Unknown Source:6)
 at com.google.firebase.firestore.g.zzh.zza (SourceFile:28)
 at com.google.firebase.firestore.g.zzi.run (Unknown Source:6)
 at android.os.Handler.handleCallback (Handler.java:873)
 at android.os.Handler.dispatchMessage (Handler.java:99)
 at android.os.Looper.loop (Looper.java:201)
 at android.app.ActivityThread.main (ActivityThread.java:6823)
 at java.lang.reflect.Method.invoke (Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
 at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:873)

I'm banging my head around this for a week.一个星期以来,我一直在思考这个问题。
Please help.请帮忙。
Thanks谢谢

You're requesting context of from itemView , but for asynchronous calls you should use app context, because context of view/fragment might not be available after the execution of that asynchronous call (in your case Glide image loading request).您正在从itemView请求上下文,但对于异步调用,您应该使用应用程序上下文,因为在执行该异步调用(在您的情况下为 Glide 图像加载请求)后,视图/片段的上下文可能不可用。

To fix this issue, simply replace要解决此问题,只需更换

holder.itemView.getContext() 

with

holder.itemView.getContext().getApplicationContext()

Option - 1: As you need the data only once, you can use get() like below:选项 - 1:由于您只需要一次数据,您可以使用get()如下所示:

firebaseFirestore
    .collection("users")
    .document(model.getUser_receiver())
    .get()
    .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if(task.isSuccessful()) {
                DocumentSnapshot documentSnapshot = task.getResult();

                //Rest of your code
            }
        }
    });

Option - 2: Add your context to addSnapshotListener like below:选项 - 2:将您的context添加到addSnapshotListener如下所示:

firebaseFirestore
    .collection("users")
    .document(model.getUser_receiver())
    .addSnapshotListener(
        holder.itemView.getContext(), 
        new EventListener<DocumentSnapshot>() 
            {

            });

As stated in official documentation :官方文档所述

Starts listening to this query using an Activity-scoped listener.使用活动范围的侦听器开始侦听此查询。
The listener will be automatically removed during onStop().侦听器将在 onStop() 期间自动删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM