如果我的数据库中没有任何类型(对象),那么应用程序会正常运行,但是在我将第一个东西添加到数据库后,它会立即崩溃,如果我再次运行它,它仍然会崩溃。
我不知道该怎么办。是因为它无法读取数据还是因为我一开始就没有创建任何东西? 35:lstType = TypeDataQuery.getAll(this);如果我删除这条线,事情就会正常运行
package com.example.myspinner;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class TypeActivity extends AppCompatActivity implements TypeAdapter.TypeCallBack {
TextView tvHeaderC;
RecyclerView rcListCode;
ArrayList<Type> lstType;
TypeAdapter typeAdapter;
FloatingActionButton fbTypeAdd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_type);
tvHeaderC = findViewById(R.id.tvTypeHeader);
rcListCode = findViewById(R.id.rvTypeList);
fbTypeAdd = findViewById(R.id.fbTypeAdd);
fbTypeAdd.setOnClickListener(view -> addTypeDialog());
lstType = new ArrayList<>();
lstType = TypeDataQuery.getAll(this);
typeAdapter = new TypeAdapter(lstType);
typeAdapter.setTypeCallBack((TypeAdapter.TypeCallBack) this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rcListCode.setAdapter(typeAdapter);
rcListCode.setLayoutManager(linearLayoutManager);
}
void addTypeDialog()
{
AlertDialog.Builder alertDialog = new AlertDialog.Builder(TypeActivity.this);
alertDialog.setTitle("Thêm mới");
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_add_type, null);
alertDialog.setView(dialogView);
EditText edTypeName = dialogView.findViewById(R.id.edTypeName);
alertDialog.setPositiveButton("Đồng ý", ((dialog, which) ->
{
String name = edTypeName.getText().toString();
if (name.isEmpty())
Toast.makeText(TypeActivity.this, "Nhập dữ liệu không hợp lệ", Toast.LENGTH_LONG).show();
else {
Type type = new Type(0, name);
long id = TypeDataQuery.insert(TypeActivity.this, type);
if (id > 0) {
Toast.makeText(TypeActivity.this, "Thêm loại thành công.", Toast.LENGTH_LONG).show();
resetData();
dialog.dismiss();
}
}
}
));
alertDialog.setNegativeButton("Hủy", ((dialog, which) ->
{
dialog.dismiss();
}
));
alertDialog.create();
alertDialog.show();
}
void resetData() {
lstType.clear();
lstType.addAll(TypeDataQuery.getAll(TypeActivity.this));
typeAdapter.notifyDataSetChanged();
}
void updateUserDialog(Type type) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(TypeActivity.this);
alertDialog.setTitle("Cập nhật");
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_add_type, null);
alertDialog.setView(dialogView);
EditText edName = (EditText) dialogView.findViewById(R.id.edTypeName);
edName.setText(type.getName());
alertDialog.setPositiveButton("Đồng ý", (dialog, which) -> {
type.setName(edName.getText().toString());
if (type.name.isEmpty())
Toast.makeText(TypeActivity.this, "Nhập dữ liệu không hợp lệ", Toast.LENGTH_LONG).show();
else {
int id = TypeDataQuery.update(TypeActivity.this, type);
if (id > 0) {
Toast.makeText(TypeActivity.this, "Cập nhật người dùng thành công.", Toast.LENGTH_LONG).show();
resetData();
dialog.dismiss();
}
}
});
alertDialog.setNegativeButton("Hủy", (dialog, which) -> {
dialog.dismiss();
});
alertDialog.create();
alertDialog.show();
}
@Override
public void onItemDeleteClicked(Type type, int position) {
boolean rs = TypeDataQuery.delete(TypeActivity.this, type.id);
if (rs) {
Toast.makeText(this, "Xoá thành công", Toast.LENGTH_LONG).show();
resetData();
} else {
Toast.makeText(this, "Xoá thất bại", Toast.LENGTH_LONG).show();
}
}
@Override
public void onItemEditClicked(Type type, int position) {
updateUserDialog(type);
}
}
package com.example.myspinner;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class UserDBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = utils.DATABASE_NAME;
private static final int DATABASE_VERSION = 4;
public UserDBHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_USER_TABLE = "CREATE TABLE " + utils.TABLE_USER + " ("
+ utils.COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ utils.COLUMN_USER_NAME + " TEXT, "
+ utils.COLUMN_USER_AVATAR + " TEXT" + ");";
String CREATE_TYPE_TABLE = "CREATE TABLE " + utils.TABLE_TYPE + " ("
+ utils.COLUMN_TYPE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ utils.COLUMN_TYPE_NAME + " TEXT" + ");" ;
db.execSQL(CREATE_USER_TABLE);
db.execSQL(CREATE_TYPE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + utils.TABLE_USER);
db.execSQL("DROP TABLE IF EXISTS " + utils.TABLE_TYPE);
onCreate(db);
}
}
package com.example.myspinner;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
public class TypeDataQuery {
public static long insert(Context context, Type type)
{
UserDBHelper userDBHelper = new UserDBHelper(context);
SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(utils.COLUMN_TYPE_NAME, type.name);
long rs = sqLiteDatabase.insert(utils.TABLE_TYPE, null, values);
return (rs);
}
public static ArrayList<Type> getAll(Context context)
{
ArrayList<Type> lstUser = new ArrayList<>();
UserDBHelper userDBHelper = new UserDBHelper(context);
SQLiteDatabase db = userDBHelper.getReadableDatabase();
Cursor cs = db.rawQuery("Select * from " + utils.TABLE_TYPE, null);
cs.moveToFirst();
while (!cs.isAfterLast())
{
int id = cs.getInt(0);
String name = cs.getString(1);
Type type = new Type(id, name);
lstUser.add(type);
cs.moveToNext();
}
cs.close();
db.close();
return lstUser;
}
public static boolean delete(Context context, int id)
{
UserDBHelper userDBHelper = new UserDBHelper(context);
SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
int rs = sqLiteDatabase.delete(utils.TABLE_TYPE, utils.COLUMN_TYPE_ID+"=?", new String[]{String.valueOf(id)});
return (rs > 0);
}
public static int update(Context context, Type type)
{
UserDBHelper userDBHelper = new UserDBHelper(context);
SQLiteDatabase sqLiteDatabase = userDBHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(utils.COLUMN_TYPE_NAME, type.name);
int rs = sqLiteDatabase.update(utils.TABLE_TYPE, values, utils.COLUMN_TYPE_ID+"=?", new String[] {String.valueOf(type.id)} );
return (rs);
}
}
package com.example.myspinner;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.TypeViewHolder> {
ArrayList<Type> lstType;
Context context;
TypeCallBack typeCallBack;
public TypeAdapter(ArrayList<Type> lstType) {
this.lstType = lstType;
}
public void setTypeCallBack(TypeCallBack typeCallBack)
{
this.typeCallBack = typeCallBack;
}
@NonNull
@Override
public TypeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View typeView = inflater.inflate(R.layout.layoutitem, parent, false);
return new TypeViewHolder(typeView);
}
@Override
public void onBindViewHolder(@NonNull TypeViewHolder holder, int position) {
Type item = lstType.get(position);
if(item != null)
{
holder.tvName.setText(item.getName());
holder.ivEdit.setOnClickListener(view -> typeCallBack.onItemEditClicked(item, position));
holder.ivDelete.setOnClickListener(view -> typeCallBack.onItemDeleteClicked(item, position));
}
}
@Override
public int getItemCount() {
return lstType.size();
}
static class TypeViewHolder extends RecyclerView.ViewHolder
{
TextView tvName;
ImageView ivEdit;
ImageView ivDelete;
public TypeViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvTypeName);
ivEdit = itemView.findViewById(R.id.ivTypeEdit);
ivDelete = itemView.findViewById(R.id.ivTypeDelete);
}
}
public interface TypeCallBack
{
void onItemDeleteClicked(Type type, int position);
void onItemEditClicked(Type type, int position);
}
}
package com.example.myspinner;
public class Type {
int id;
String name;
public Type(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
如果没有要提取的数据,则
moveToFirst
的结果将为假(无法完成移至第一行)。如果在不检查结果的情况下尝试提取数据,则会发生异常(崩溃)。
您必须检查
moveToFirst
是否成功。
使用起来更简单、更简洁:-
Cursor cs = db.rawQuery("Select * from " + utils.TABLE_TYPE, null);
//cs.moveToFirst();
while (cs.moveToNext)
{
int id = cs.getInt(0);
String name = cs.getString(1);
Type type = new Type(id, name);
lstUser.add(type);
}
cs.moveToFirst
行已被注释掉(否则将跳过 1 行)。显然,该行可以删除(保留以进行说明)。moveToNext
将有效地从第一行之前的位置移动到第一行,如果无法移动则返回 false。