android - 从一列更新 SQLite 一个值
问题描述
我有一个使用 RecyclerView 和 SQLite 的应用程序。
我的数据库是:
public class countersDatabase extends SQLiteOpenHelper {
private static final String DB_NAME = "Counters.db";
private static final String DB_TABLE = "Counters_Table";
//Columns
private static final String ID = "ID";
private static final String ITEM_INDEX = "ITEM_INDEX";
private static final String COLOR = "COLOR";
private static final String MAXTIME = "MAXTIME";
private static final String NAME = "NAME";
private static final String TYPE = "TYPE";
private static final String USINGTIME = "USINGTIME";
private static final String CREATE_TABLE = "CREATE TABLE " + DB_TABLE + " (" +
ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + //i = 0
ITEM_INDEX + " INTEGER, " + //i = 1
COLOR + " TEXT, " + //i = 2
MAXTIME + " TEXT, " + //i = 3
NAME + " TEXT, " + //i = 4
TYPE + " TEXT, " + //i = 5
USINGTIME + " TEXT " + ") "; //i = 6
public countersDatabase(Context context) {
super(context, DB_NAME, null, 1);
};
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
onCreate(sqLiteDatabase);
}
public boolean insertData(int item_index ,String color, String maxTime, String name, String type, String usingTime) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(ITEM_INDEX, item_index);
contentValues.put(COLOR, color);
contentValues.put(MAXTIME, maxTime);
contentValues.put(NAME, name);
contentValues.put(TYPE, type);
contentValues.put(USINGTIME, usingTime);
long result = db.insert(DB_TABLE, null, contentValues);
if (result == -1) return false;
else
return true;
}
public ArrayList<Counter> getAllData() {
ArrayList<Counter> arrayList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + DB_TABLE, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
int item_index = cursor.getInt(1);
String color = cursor.getString(2);
String maxTime = cursor.getString(3);
String name = cursor.getString(4);
String type = cursor.getString(5);
String usingTime = cursor.getString(6);
Counter counter = new Counter(id, item_index, color, maxTime, name, type, usingTime);
arrayList.add(counter);
}
return arrayList;
}
public void updateTimeOnData(int position, String time) {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("UPDATE "+DB_TABLE+" SET "+USINGTIME+" = '"+time+"' WHERE "+ITEM_INDEX+" = "+position+";");
db.close();
}
public void deleteDataItem(int position) {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + DB_TABLE + " WHERE " +
ITEM_INDEX + " = " + position + ";");
db.execSQL("UPDATE " + DB_TABLE + " SET " + ITEM_INDEX + " = " +
ITEM_INDEX + " -1 " + " WHERE " + ITEM_INDEX + " > " + position + ";");
db.close();
}
}
当我尝试updateTimeOnData(int position, String time)
从 CounterHolder 类调用如下:
public class CounterHolder extends RecyclerView.ViewHolder {
countersDatabase countersDatabase;
NumberPicker timePicker;
TextView timeLabel;
TextView txtUnderTime;
double usingHours;
double maxHours;
int counterPosition;
String counterDiffHours;
private final TextView t3_name;
private final TextView t4_type;
private final Button t5_usingTime;
private final TextView remainLabel;
private Counter counter;
private Context context;
public CounterHolder(Context context, View itemView) {
super(itemView);
(...)
itemView.setOnClickListener(view -> {
if (counter != null) {
maxHours = timeStringToDouble(counter.getMaxTime());
usingHours = timeStringToDouble(counter.getUsingTime());
counterPosition = getAdapterPosition();
TextView titleToolbarCounter = ((MainActivity)context).findViewById(R.id.titleToolbarCounter);
String name = counter.getName();
titleToolbarCounter.setText(name);
TextView usingTimeCounter = ((MainActivity)context).findViewById(R.id.txtTime);
String usingTime = counter.getUsingTime();
usingTimeCounter.setText(usingTime);
counterBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
TextView pickerLabel = ((MainActivity)context).findViewById(R.id.timePickerLabel);
pickerLabel.setText("00:30");
timeLabel = ((MainActivity)context).findViewById(R.id.txtTime);
txtUnderTime = ((MainActivity)context).findViewById(R.id.txtUnderTime);
counterDiffHours = timeDoubleToString(maxHours - usingHours);
Button minusButton = ((MainActivity)context).findViewById(R.id.minusButton);
Button plusButton = ((MainActivity)context).findViewById(R.id.plusButton);
plusButton.setOnClickListener(plusAction -> {
double preHours = timeStringToDouble((String) timeLabel.getText());
double timeInterval = timeStringToDouble((String) pickerLabel.getText());
double postHours = preHours + timeInterval;
timeLabel.setText(timeDoubleToString(postHours));
//------------ERROR NEXT LINE------------
countersDatabase.updateTimeOnData(counterPosition, timeDoubleToString(postHours)); //Line 212
counterDiffHours = timeDoubleToString(maxHours - postHours);
if (postHours/maxHours == 0) {
txtUnderTime.setText(((MainActivity)context).getResources().getString(R.string.text_under_time_ini, counterDiffHours));
} else if (postHours/maxHours <= 0.25) {
txtUnderTime.setText(((MainActivity)context).getResources().getString(R.string.text_under_time_00, counterDiffHours));
} else if (postHours/maxHours <= 0.50) {
txtUnderTime.setText(((MainActivity)context).getResources().getString(R.string.text_under_time_25, counterDiffHours));
} else if (postHours/maxHours <= 0.75) {
txtUnderTime.setText(((MainActivity)context).getResources().getString(R.string.text_under_time_50, counterDiffHours));
} else {
txtUnderTime.setText(((MainActivity)context).getResources().getString(R.string.text_under_time_75, counterDiffHours));
}
}
});
}
});
}
public void bindCounter(Counter counter) {
(...)
}
public double timeStringToDouble(String time) {
String hoursString = time.substring(0,2);
String minutesString = time.substring(3);
double hours = Double.parseDouble(hoursString);
double minutes = Double.parseDouble(minutesString);
return hours + minutes/60;
}
public String timeDoubleToString(double time) {
BigDecimal bigDecimal = new BigDecimal(String.valueOf(time));
int hours = bigDecimal.intValue();
double decimalHours = bigDecimal.subtract(new BigDecimal(hours)).doubleValue();
int minutes = (int) (decimalHours * 60);
String hoursString;
String minutesString;
if (String.valueOf(hours).length() == 2) {
hoursString = String.valueOf(hours);
} else {
hoursString = "0" + hours;
}
if (String.valueOf(minutes).length() == 2) {
minutesString = String.valueOf(minutes);
} else {
minutesString = "0" + minutes;
}
return hoursString + ":" + minutesString;
}
}
我收到一个错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: mycounter, PID: 32064
java.lang.NullPointerException: Attempt to invoke virtual method 'void mycounter.countersDatabase.updateTimeOnData(int, java.lang.String)' on a null object reference
at mycounter.Adapters.CounterHolder.lambda$null$3$CounterHolder(CounterHolder.java:212)
at mycounter.Adapters.-$$Lambda$CounterHolder$gWMz9kyJKjdWTqootaS6M3fBw7M.onClick(Unknown Source:8)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
我也尝试编码updateTimeOnData()
如下:
public void updateTimeOnData(int position, String time) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(USINGTIME, time);
db.update(DB_TABLE, cv, ITEM_INDEX + "= ?", new String[] {String.valueOf(position)});
db.close();
}
但是出现了同样的错误...
有谁知道哪里可能是错误?因为如果我登录counterPosition
并且timeDoubleToString(postHours)
我得到正确的值......
解决方案
您永远不会在 中初始化countersDatabase
,CounterHolder
因此NullPointerException
.
推荐阅读
- java - 在 MacOS 上安装 R 并从源代码编译包 - 组件和步骤以使事情正常运行
- reactjs - 如何在 TypeScript 中创建一个让我处理事件的 React 组件?
- sql - 如何计算两个日期之间的月数和天数,而不在 SQL Server 中返回负值
- java - 为什么 JSON 没有被解组到我的 Java 类中?
- python - 如何使用 tkinter 和 turtle 获得鼠标位置?
- apache-poi - 由于 xmlbeans 在 weblogic 中卡住了线程
- javascript - 为什么 Phantomjs 不适用于此站点?
- sql - 为什么我的子查询使用字符串而不是字段引用?
- php - 是否可以从 PHP 文件发送标头,这完全没有任何作用
- rasa-core - Rasa 自定义操作事件丢失