【问题标题】:App crashes with IndexOutOfBoundsException when deleting firebase child with removeValue()使用 removeValue() 删除 firebase 子时,应用程序因 IndexOutOfBoundsException 而崩溃
【发布时间】:2020-11-30 17:39:05
【问题描述】:

我正在制作一个基于 firebase 实时数据库的安卓应用。我正在阅读RecyclerView 中的数据。我的RecyclerView 里有三个项目。

  1. 文本视图 = 名称
  2. 文本视图 = 数字
  3. 按钮 = 删除

当我从RecyclerView 中删除一些孩子时,可能会发生三件事:

  1. 有时它会正常删除目标孩子

  2. 有时它会删除一些其他孩子(通常在目标孩子之下。)

  3. 有时我的应用会崩溃。

这是我的适配器的代码:

public class holder extends RecyclerView.ViewHolder {
    public Button btnDelete;
    public TextView tvName;
    public TextView tvRoll;

    public holder(@NonNull View itemView) {
        super(itemView);
        btnDelete=(Button) itemView.findViewById(R.id.idDelete);
        tvName=(TextView) itemView.findViewById(R.id.idName);
        tvRoll=(TextView) itemView.findViewById(R.id.idRoll);

    }
}

这是在回收站视图中显示项目的代码和删除按钮的代码:

options = new FirebaseRecyclerOptions.Builder<basic>()
                .setQuery(myRef, basic.class)
                .build();
        adapter = new FirebaseRecyclerAdapter<basic, holder>(options) {
            @SuppressLint("SetTextI18n")
            @Override
            protected void onBindViewHolder(@NonNull holder holder, final int i, @NonNull final basic basic) {
                holder.tvName.setText(basic.getFb01name());
                holder.tvRoll.setText(basic.getFb04roll());
                holder.btnDelete.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                            myRef.child(getRef(i).getKey()).removeValue();
                    }
                });
            }

            @NonNull
            @Override
            public holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
                return new holder(v);
            }
        };
        //------------------------------
        adapter.startListening();
        Userlist.setAdapter(adapter);
        //-----------------------------------

我猜不出问题出在哪里。

还请提供一个切实可行的解决方案。

这是崩溃报告:

2020-11-30 23:27:45.968 10796-10796/com.my App Name E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.my App Name, PID: 10796
    java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.firebase.ui.common.BaseObservableSnapshotArray.getSnapshot(BaseObservableSnapshotArray.java:70)
        at com.firebase.ui.database.FirebaseRecyclerAdapter.getRef(FirebaseRecyclerAdapter.java:112)
        at com.my App Name.ViewActivity$1$1.onClick(ViewActivity.java:72)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2020-11-30 23:27:46.701 1467-10685/com.google.android.googlequicksearchbox E/sb.v.u.LiteSuggestSourc: On-device lite suggest model loading error.
2020-11-30 23:27:46.818 1467-1774/com.google.android.googlequicksearchbox E/MDD: DownloadProgressMonitor: Can't find file group for uri: android://com.google.android.googlequicksearchbox/files/sharedminusonemodule/shared/SharedMinusOneData.pb.tmp

【问题讨论】:

  • 将myRef.child(getRef(i).getKey()).removeValue() 替换为getRef(i).removeValue()。我不认为它会解决问题(否则我会把它作为答案发布),但它更惯用,不太可能导致竞争条件。
  • 非常感谢。你一如既往地及时提供帮助。但很遗憾,上述修改没有奏效。你能花点心思重新考虑一下吗?
  • 能分享一下皮疹报告吗
  • 我的 firebase 参考是这样的:myRef = myfire.getReference().child("Users").child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2");
  • 嘿@Zain。 getRef() 是 FirebaseUI 适配器中的一种方法,它为适配器中位于 i 位置的项目返回 DatabaseReference。代码:github.com/firebase/FirebaseUI-Android/blob/master/database/src/…

标签: java android firebase-realtime-database firebaseui


【解决方案1】:

似乎当您在按钮onClick 回调中访问Firebase getRef(i) 时,它可以引用错误的位置i 导致IndexOutOfBoundsException

因此,我们将在回调之外获取密钥,如下所示:

options = new FirebaseRecyclerOptions.Builder<basic>()
            .setQuery(myRef, basic.class)
            .build();
    adapter = new FirebaseRecyclerAdapter<basic, holder>(options) {
        @SuppressLint("SetTextI18n")
        @Override
        protected void onBindViewHolder(@NonNull holder holder, final int i, @NonNull final basic basic) {
            holder.tvName.setText(basic.getFb01name());
            holder.tvRoll.setText(basic.getFb04roll());
            String refKey = getRef(i).getKey(); // <<<<<< Here is the change
            
            holder.btnDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    myRef.child(refKey)).removeValue();
                }
            });
        }

        @NonNull
        @Override
        public holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
            return new holder(v);
        }
    };

【讨论】:

  • 非常感谢@Zain 提供实用的解决方案。
猜你喜欢
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
相关资源
最近更新 更多