java - 使用 removeValue() 删除 firebase 子时,应用程序因 IndexOutOfBoundsException 而崩溃
问题描述
我正在制作一个基于firebase Realtime database的 android 应用程序。我正在读取RecyclerView
. 我的RecyclerView
.
- 文本视图 = 名称
- 文本视图 = 数字
- 按钮 = 删除
当我从我的RecyclerView
三件事中删除一些孩子时,可能会发生:
有时它会正常删除目标孩子
有时它会删除其他一些孩子(通常在目标孩子之下。)
有时我的应用程序崩溃。
这是我的适配器的代码:
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
解决方案
似乎当您getRef(i)
在按钮onClick
回调中访问 Firebase 时,它可以引用错误的位置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);
}
};