[英]Room database error while deleting row onclick
我已將會議室 SQLite數據庫定義為:
@Database(entities = {PlaceSaved.class},version = 1)
public abstract class PlaceDatabase extends RoomDatabase {
public abstract DatabaseInterface databaseInterface();
@Override
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
return null;
}
@Override
protected InvalidationTracker createInvalidationTracker() {
return null;
}
}
定義在:
@Entity
public class PlaceSaved {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "time")
private String time;
@ColumnInfo(name="title")
private String title;
public PlaceSaved(){
}
public PlaceSaved(String time, String title) {
this.time = time;
this.title = title;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
相應的DAO為:
@Dao
public interface DatabaseInterface {
@Query("SELECT * FROM placesaved")
List<PlaceSaved> getAllItems();
@Insert
void insertAll(PlaceSaved... todoListItems);
@Delete
public void delete(PlaceSaved... todoListItems);
@Update
public void update(PlaceSaved...todoListItems);
}
並且這些數據通過recyclerview顯示,每個項目的布局定義為:
<TextView
android:id="@+id/secondLine"/>
<TextView
android:id="@+id/firstLine"/>
<ImageButton
android:id="@+id/delicon"/>
現在,我想使用此delicon
ImageButton
刪除相應的條目。 因此,我嘗試將其放入適配器中( 注意:已更新,請參閱末尾的更新代碼 ):
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.ViewHolder> {
//PlaceDatabase db;
List<PlaceSaved> items;
public PlacesAdapter(List<PlaceSaved> items) {
this.items = items;
}
@Override
public PlacesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.places_list_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(PlacesAdapter.ViewHolder holder, final int position) {
holder.name.setText(items.get(position).getTitle());
holder.time.setText(items.get(position).getTime());
// holder.delbutton.setClickable(true);
holder.delbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
removeItem(items);
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView name;
public TextView time;
public ImageButton delbutton;
public ViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.secondLine);
time= itemView.findViewById(R.id.firstLine);
delbutton = itemView.findViewById(R.id.delicon);
}
}
private void removeItem(PlaceSaved infoItem){
PlaceSaved placeSaved = new PlaceSaved();
placeSaved.delete(infoItem);
}
}
並將recyclerview稱為:(**注:onCreate已更新並在末尾發布)
public class PlacesActivity extends AppCompatActivity {
FloatingActionButton fab, fab1, fab2, fab3;
LinearLayout fabLayout1, fabLayout2, fabLayout3;
boolean isFABOpen=false;
View fabBGLayout;
public static RecyclerView recyclerView;
public static RecyclerView.Adapter adapter;
List<PlaceSaved> items;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_layout);
//whenever the activity is started, it reads data from database and stores it into
// local array list 'items'
final PlaceDatabase db = Room.databaseBuilder(getApplicationContext(), PlaceDatabase.class, "production")
.build();
//it is very bad practice to pull data from Room on main UI thread,
// that's why we create another thread which we use for getting the data and displaying it
Runnable r = new Runnable() {
@Override
public void run() {
items = db.databaseInterface().getAllItems();
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplication()));
adapter = new PlacesAdapter(items);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
};
這給出了編譯時間錯誤:
PlacesAdapter.java
Error:(43, 22) error: incompatible types: List<PlaceSaved> cannot be converted to PlaceSaved
Error:(68, 17) error: cannot find symbol method delete(PlaceSaved)
請幫助我解決這個問題。
更新根據Vishu的回答,我已將適配器更新為:
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.ViewHolder> {
private static final String TAG = "MyActivity";
List<PlaceSaved> items;
PlaceDatabase db;
public PlacesAdapter(List<PlaceSaved> items, PlaceDatabase db) {
this.items = items;
this.db = db;
}
@Override
public PlacesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.places_list_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final PlacesAdapter.ViewHolder holder, final int position) {
holder.name.setText(items.get(position).getTitle());
holder.time.setText(items.get(position).getTime());
holder.delbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
removeItem(items.get(holder.getAdapterPosition()));
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView name;
public TextView time;
public ImageButton delbutton;
public ViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.secondLine);
time= itemView.findViewById(R.id.firstLine);
delbutton = itemView.findViewById(R.id.delicon);
}
}
private void removeItem(PlaceSaved infoItem){
// db.delete(infoItem);
Log.v(TAG, "remove Item called");
}
}
並在PlacesActivity中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_layout);
final PlaceDatabase db = Room.databaseBuilder(getApplicationContext(), PlaceDatabase.class, "production")
.build();
Runnable r = new Runnable() {
@Override
public void run() {
items = db.databaseInterface().getAllItems();
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplication()));
adapter = new PlacesAdapter(items, db);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
};
這仍然給語法錯誤:
Error:(71, 17) error: cannot find symbol method delete(PlaceSaved)
和2條警告(並非由於Vishu的回答,它之前曾出現過):
PlaceSaved.java
Warning:(11, 8) There are multiple good constructors and Room will pick the no-arg constructor. You can use the @Ignore annotation to eliminate unwanted constructors.
PlaceDatabase.java
Warning:(13, 17) Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.
錯誤:更新:
添加db.databaseInterface().delete(infoItem);
在removeitem中給出:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:164)
at android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:211)
at DatabaseInterface_Impl.delete(DatabaseInterface_Impl.java:94)
at PlacesAdapter.removeItem(PlacesAdapter.java:69)
at PlacesAdapter.access$000(PlacesAdapter.java:20)
at PlacesAdapter$1.onClick(PlacesAdapter.java:45)
at android.view.View.performClick(View.java:6294)
為什么在removeItem()
傳遞PlaceSaved
ArrayList
。 removeItem()
僅接受PlaceSaved
。
因此將onclick
更改為
removeItem(items.get(holder.getAdapterPosition()));
讓holder
最終在方法簽名final PlacesAdapter.ViewHolder holder
否則將無法編譯。
您已經在PlaceDatabase
定義了delete
並且正在調用PlaceSaved
,這就是為什么您得到Error:(68, 17) error: cannot find symbol method delete(PlaceSaved)
PlaceSaved
Error:(68, 17) error: cannot find symbol method delete(PlaceSaved)
你可以通過db
從PlacesAdapter
就像items
一樣PlacesAdapter(items, db)
更改
adapter = new PlacesAdapter(items);
至
adapter = new PlacesAdapter(items, db);
現在,您的PlacesAdapter將具有db
實例。 您可以替換placeSaved.delete(infoItem);
與db.delete(infoItem)
更改
List<PlaceSaved> items;
public PlacesAdapter(List<PlaceSaved> items) {
this.items = items;
}
至
List<PlaceSaved> items;
PlaceDatabase db;
public PlacesAdapter(List<PlaceSaved> items, PlaceDatabase db) {
this.items = items;
this.db = db
}
和改變
placeSaved.delete(infoItem);
至
db.databaseInterface().delete(infoItem);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.