我正在尝试从NSLayoutAttributeTrailing
数据库填充的RecyclerView
中删除项目,我收到以下错误:
Realm
假设 我猜我正在尝试访问它已被删除,但我不明白在哪里。
上下文 我正在显示一个城市列表并且长按一个项目会显示一个对话框,要求确认删除。
该项目在数据库中被删除,因为当我重新启动应用程序时,它已不存在了。
领域到ArrayList
java.lang.IllegalStateException: Illegal State:
Object is no longer valid to operate on. Was it deleted by another thread?
对话框代码
public static ArrayList<City> getStoredCities(){
RealmQuery<City> query = getRealmInstance().where(City.class);
final RealmResults<City>results =
realm.where(City.class)
.findAllSorted("timestamp", Sort.DESCENDING);
results.size();
ArrayList<City> cityArrayList = new ArrayList<>();
for(int i = 0; i< results.size(); i++){
cityArrayList.add(results.get(i));
}
return cityArrayList;
}
删除项目的领域方法
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
RealmHelper.removeCity(cityArrayList.get(position));
cityArrayList.remove(position);
mRecyclerView.removeViewAt(position);
mCityListAdapter.notifyItemRemoved(position);
mCityListAdapter.notifyItemRangeChanged(position, cityArrayList.size());
mCityListAdapter.notifyDataSetChanged();
}
});
日志
public static void removeCity(City city){
RealmResults<City> result = realm.where(City.class).equalTo("cityName", city.getCityName()).findAll();
realm.beginTransaction();
result.deleteAllFromRealm();
realm.commitTransaction();
}
适配器代码
07-28 11:02:08.461 9461-9461/com.ilepez.weatherapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ilepez.weatherapp, PID: 9461
java.lang.IllegalStateException: Illegal State:
Object is no longer valid to operate on. Was it deleted by another thread?
at io.realm.internal.UncheckedRow.nativeGetString(Native Method)
at io.realm.internal.UncheckedRow.getString(UncheckedRow.java:153)
at io.realm.CityRealmProxy.realmGet$cityName(CityRealmProxy.java:75)
at com.ilepez.weatherapp.data.model.City.getCityName(City.java:41)
at com.ilepez.weatherapp.adapter.CityListAdapter.onBindViewHolder(CityListAdapter.java:56)
at com.ilepez.weatherapp.adapter.CityListAdapter.onBindViewHolder(CityListAdapter.java:20)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5768)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5801)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5037)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:588)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3260)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:2788)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.design.widget.NavigationView.onMeasure(NavigationView.java:218)
at android.view.View.measure(View.java:20151)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1108)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20151)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6328)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:3158)
at android.view.View.measure(View.java:20151)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2594)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1549)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1841)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7403)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCall
答案 0 :(得分:6)
好的,所以你正在调用adapter.notifyDataSetChanged()
,因此不需要任何其他notify___
方法(数据集更改无论如何都会禁用动画。)
在这种情况下,最简单(也是最有效)的处理方式是直接使用RealmResults
,而不是将每个元素检索到ArrayList
,然后使用完全相同的方式。< / p>
所以应该是这样的
public static RealmResults<City> getStoredCities(){
RealmQuery<City> query = getRealmInstance().where(City.class);
return realm.where(City.class)
.findAllSorted("timestamp", Sort.DESCENDING);
}
和
public static void removeCity(City city){
final String cityName = city.getCityName();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<City> result = realm.where(City.class).equalTo("cityName", cityName).findAll();
result.deleteAllFromRealm();
}
});
}
和
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
RealmHelper.removeCity(getItem(position));
}
});
和
// dependency: compile 'io.realm:android-adapters:1.3.0'
// <-- for Realm 3.x+, use 2.0.0
// for Realm 5.x+, use 3.0.0
public class CityListAdapter extends RealmRecyclerViewAdapter<City, CityListViewHolder> {
OnItemClickListener onItemClickListener;
OnItemLongClickListener onItemLongClickListener;
public CityListAdapter(@NonNull Context context,
@Nullable OrderedRealmCollection<City> data,
OnItemClickListener onItemClickListener,
OnItemLongClickListener onItemLongClickListener) {
super(context, data, true);
this.onItemClickListener = onItemClickListener;
this.onItemLongClickListener = onItemLongClickListener;
}
@Override
public CityListViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.city_item_navigation_viewholder, parent, false);
CityListViewholder cityListViewholder = new CityListViewholder(view, parent.getContext());
return cityListViewholder;
}
@Override
public void onBindViewHolder(CityListViewholder holder, int position) {
holder.cityName.setText(getItem(position).getCityName());
holder.bindClick(position, onItemClickListener);
holder.bindLongClick(position, onItemLongClickListener);
}
public static class CityListViewholder extends RecyclerView.ViewHolder {
TextView cityName;
ImageView cityIcon;
public CityListViewholder(View itemView,
Context context) {
super(itemView);
cityName = (TextView)itemView.findViewById(R.id.city_name);
cityIcon = (ImageView)itemView.findViewById(R.id.city_icon);
}
public void bindClick(final int position, final OnItemClickListener onItemClickListener){
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListener.onItemClick(position);
}
});
}
public void bindLongClick(final int position, final OnItemLongClickListener onItemLongClickListener) {
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
onItemLongClickListener.onItemLongClick(position);
return true;
}
});
}
}
}
使用RealmRecyclerViewAdapter
会在结果发生变化时致电notifyDataSetChanged()
。