java - Android SQLite数据库未完全提交?更改直到 Activity 结束?

标签 java android sqlite

很抱歉,冗长的描述,如果不给您一些背景知识,很难描述我的问题。

好的,所以我有一个使用一个SQLite数据库并在其中有两个表的应用程序,表1和表2。日志活动具有一个选项卡式viewpager,并且在该viewpager的每个视图中都是一个列表视图(Tab 1列表视图和Tab 2列表视图),其中包含来自数据库中相应表(表1和表2)的数据。

因此,当我进入带有Fragment的日志活动时,我可以单击Tab 1,它将用数据库中表1中的数据填充Tab 1列表视图。当我单击Tab 2时,它将使用数据库中表2中的数据填充Tab 2列表视图。每个选项卡都有其自己的片段。 Tab 1片段和Tab 2片段。

因此,为了解释我的问题,我将仅关注我的选项卡1,因为两个选项卡在同一时间运行。

工作原理:

让我先解释一下,尽管如果我将Data X添加到我的Tab 1,Table 1中,它将用Data X填充Listview 1并将Data X添加到我的Table 1中。我可以在表1中登录Log.d,然后输入正确的数据。如果我在电话上按回去以Fragment回到我的主活动,然后决定以Fragment回到我的日志活动,它将使用数据X填充Listview 1,而数据X仍在我的表1中,因为再次我可以在表1中Log.d,然后看到已经输入了数据。如果我在进入主活动后又删除数据X并返回到日志活动,则数据X将从表1中删除就可以了,并且将从我的Listview 1中删除。删除后可以在表1中记录log.d。并看到它已从我的表1中删除。

什么不起作用:

因此,我的实际问题是,当我在数据库的表1(表1)中添加数据X和数据Y时。 Listview 1将使用Data X和Data Y填充并将Data X和Data Y插入数据库中,因为我可以Log.d表并看到Data X和Data Y已输入到我的表中。...但是现在可以说我决定立即删除数据Y(虽然这次从未离开Log Activity),但它不会从表1中删除,但是会从列表视图1中删除数据Y。所以现在,当我Log.d我的表1时我看到我的表1中仍然有数据X和数据Y,但是我的列表视图1仅显示了数据X。如果现在按返回按钮并返回到我的主活动,然后再次返回到我的日志活动中,将使用数据X和数据Y填充我的Tab 1 Listview 1,因为实际上并未从表1中删除数据Y。

好像我无法删除或编辑未输入的数据到表中,而不先离开日志活动并返回到表中以“提交/完成”输入表1的数据。我的插入,更新和删除功能添加新数据并退出到Logs Activity之后,我离开了Logs Activity后,工作正常。但是,如果我添加新数据然后立即尝试更改该数据,则我的删除和更新功能将无法正常工作。我的Listview正在更新并正确填充。

我研究和尝试过的内容:

我确保我有一个SQLiteOpenHelper实例和我的SQLiteDatabase变量。我还尝试过在每次插入,编辑或删除之前打开数据库,然后在插入,编辑或删除之后关闭数据库。它似乎没有任何作用。目前,我已经关闭了onPause()并再次在onResume()上打开了数据源。最后,我尝试为每个Insert,Update或Delete设置一个setTransactionSuccessful(),然后在beginTransaction()之后设置endTransaction()。

当前思想:

我认为这可能与表中条目的ID有关。我相信当向表中添加新条目时,ID应该自动递增。添加数据然后立即尝试更改数据时,它们可能不是我期望的那样。但是,当我退出Log活动并返回时,ID不应更改,因此我不太确定。

码:

这是我的一个Tab片段的代码,由于文件的大小,我剥离了很多东西。

public class LogOilTabFragment extends Fragment  implements View.OnClickListener{

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    mContext = getActivity();

    DataSource.getInstance(mContext).open();

    mListView = (ListView) view.findViewById(R.id.oil_list);

    arrayOfLogs = new ArrayList<Log>();

    arrayOfLogs = DataSource.getInstance(mContext).getAllLogs(LogsContract.OilTable.TAG);
    mAdapter = new LogAdapter(getActivity(), arrayOfLogs);
    mListView.setAdapter(mAdapter);
    }

}


@Override
public void onResume() {
    DataSource.getInstance(mContext).open();
    super.onResume();
}

@Override
public void onPause() {
    DataSource.getInstance(mContext).close();
    super.onPause();
}



private void addLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.add_edit_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
    alert.setView(view);

    alert.setPositiveButton("ADD LOG", new DialogInterface.OnClickListener(){
        public void onClick(DialogInterface dialog, int whichButton) {
            String date = dateInput.getText().toString();
            String amount = amountInput.getText().toString();
            String miles = milesInput.getText().toString();

            if (error_count == 0) {
                Log log = new Log();
                log.setmDate(date);
                log.setmAmount(amount);
                log.setmMiles(miles);

                DataSource.getInstance(mContext).insert(date, amount, miles, OilTable.TAG);
                mAdapter.add(log);
                mAdapter.notifyDataSetChanged();

                mListView.smoothScrollToPosition(mPosition);
            }
        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {

        }
    });
    alert.show();



}

private void editLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.add_edit_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    alert.setView(view);

    Log log = null;
    //Pre fill in the edit text views with the data already in the database
    if (mAdapter.getCount() > 0 && mPosition >= 0) {
        log = (Log) mAdapter.getItem(mPosition);
        dateInput.setText(log.getmDate());
        amountInput.setText(log.getmAmount());
        milesInput.setText(log.getmMiles());
    }

    alert.setPositiveButton("EDIT LOG", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            String date = dateInput.getText().toString();
            String amount = amountInput.getText().toString();
            String miles = milesInput.getText().toString();

            if (error_count == 0) {

                Log log = (Log) mAdapter.getItem(mPosition);
                                  DataSource.getInstance(mContext).edit(log.getmId(), date, amount, miles, OilTable.TAG);
                mAdapter.clear();
                arrayOfLogs = new ArrayList<Log>();

                arrayOfLogs = DataSource.getInstance(mContext).getAllLogs(OilTable.TAG);
                mAdapter.addAll(arrayOfLogs);
                mAdapter.notifyDataSetChanged();

            }
        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //Do Nothing
        }
    });

    alert.show();
}

private void deleteLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.delete_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    alert.setView(view);

    alert.setPositiveButton("DELETE LOG", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            Log log = null;

            if (mAdapter.getCount() > 0) {
                log = (Log) mAdapter.getItem(mPosition);
                                        DataSource.getInstance(mContext).delete(log, OilTable.TAG);

                mAdapter.remove(log);
                mAdapter.notifyDataSetChanged();
            }

        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //Do Nothing
        }
    });

    alert.show();

}


这是我的类,具有从数据源插入,更新和删除代码

public class DataSource {

public static DataSource dataSource;

private SQLiteDatabase mSQLiteDatabase;
private LogsDBHelper mLogsDBHelper; //LogsDBHelper Extends SQLiteOpenHelper
}

//String of column names for the oil sqlite database.
private String[] mAllOilColumns = {
        OilTable.COLUMN_ID,
        OilTable.COLUMN_DATE,
        OilTable.COLUMN_AMOUNT,
        OilTable.COLUMN_MILES};

//String of column names for the coolant sqlite database.
private String[] mAllCoolantColumns = {
        OilTable.COLUMN_ID,
        OilTable.COLUMN_DATE,
        OilTable.COLUMN_AMOUNT,
        OilTable.COLUMN_MILES};

    public static synchronized DataSource getInstance(Context context) {

    if (dataSource == null) {
        dataSource = new DataSource(context.getApplicationContext());
    }
    return dataSource;
}

private DataSource(Context context) {
    mLogsDBHelper = new LogsDBHelper(context); //LogsDBHelper Extends SQLiteOpenHelper
}

public void open() throws SQLiteException {
    mSQLiteDatabase = mLogsDBHelper.getWritableDatabase();
}

public void close() {
    mLogsDBHelper.close();
   // mSQLiteDatabase.close();
}



//Method takes a string and depending on the string creates a query from the correct
//database table and returns the amount of items in the table
public int getLength(String tag){
    Cursor cursor;

    switch (tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME,
                    mAllOilColumns, null, null, null, null, null);
            return cursor.getCount();
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME,
                    mAllCoolantColumns, null, null, null, null, null);
            return cursor.getCount();
    }
    return 0;
}

//Inserts a log into the correct sqlite table with the passed values
public void insert(String date, String amount, String miles, String tag) {
    ContentValues values = new ContentValues();

    switch (tag) {
        case OilTable.TAG:
            values.put(OilTable.COLUMN_DATE, date);
            values.put(OilTable.COLUMN_AMOUNT, amount);
            values.put(OilTable.COLUMN_MILES, miles);
            mSQLiteDatabase.insert(OilTable.TABLE_NAME, null, values);
            break;
        case CoolantTable.TAG:
            values.put(CoolantTable.COLUMN_DATE, date);
            values.put(CoolantTable.COLUMN_AMOUNT, amount);
            values.put(CoolantTable.COLUMN_MILES, miles);
            mSQLiteDatabase.insert(CoolantTable.TABLE_NAME, null, values);
            break;

    }
}

//Edits/Updates a log into the correct sqlite table with the passed values
public void edit(Long id, String date, String amount, String miles, String tag){
    ContentValues values = new ContentValues();

    switch (tag) {
        case OilTable.TAG:
            values.put(OilTable.COLUMN_DATE, date);
            values.put(OilTable.COLUMN_AMOUNT, amount);
            values.put(OilTable.COLUMN_MILES, miles);
            mSQLiteDatabase.update(OilTable.TABLE_NAME, values, "_id=" + id, null);
            break;
        case CoolantTable.TAG:
            values.put(CoolantTable.COLUMN_DATE, date);
            values.put(CoolantTable.COLUMN_AMOUNT, amount);
            values.put(CoolantTable.COLUMN_MILES, miles);
            mSQLiteDatabase.update(CoolantTable.TABLE_NAME, values, "_id=" + id, null);
            break;
    }
}

//Deletes a log into the correct sqlite table based on the log id.
public void delete(Log log, String tag) {
    long id = log.getmId();

    switch(tag) {
        case OilTable.TAG:
            mSQLiteDatabase.delete(OilTable.TABLE_NAME,
                    OilTable.COLUMN_ID + " = " + id, null);
            break;
        case CoolantTable.TAG:
            mSQLiteDatabase.delete(CoolantTable.TABLE_NAME,
                    CoolantTable.COLUMN_ID + " = " + id, null);
            break;
    }
}

//Returns an Arraylist of all of the logs from the table specified from the passed in value.
public ArrayList getAllLogs(String tag){

    ArrayList logs = new ArrayList();
    Cursor cursor;
    Log log;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME,
                mAllOilColumns, null, null, null, null, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                log = cursorToLog(cursor);
                logs.add(log);
                cursor.moveToNext();
            }
            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME,
                    mAllCoolantColumns, null, null, null, null, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                log = cursorToLog(cursor);
                logs.add(log);
                cursor.moveToNext();
            }
            cursor.close();
            break;
    }

    return logs;
}

//Used in local method getAllLogs()
private Log cursorToLog(Cursor cursor) {
    Log log = new Log();
    log.setmId(cursor.getLong(0));
    log.setmDate(cursor.getString(1));
    log.setmAmount(cursor.getString(2));
    log.setmMiles(cursor.getString(3));
    return log;
}


//Used to get all of the dates from the specified database in the call.
public String[] getAllDates(String tag){
    Cursor cursor;
    int index;
    String[] dates = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_DATE);
            dates = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                dates[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_DATE);
            dates = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                dates[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }
    return dates;
}

//Used to get all of the amounts from the specified database in the call.
public String[] getAllAmounts(String tag){
    Cursor cursor;
    int index;
    String[] amounts = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_AMOUNT);
            amounts = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                amounts[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_AMOUNT);
            amounts = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                amounts[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }

    return amounts;
}

//Used to get all of the miles from the specified database in the call.
public String[] getAllMiles(String tag){
    Cursor cursor;
    int index;
    String[] miles = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_MILES);
            miles = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                miles[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_MILES);
            miles = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                miles[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }

    return miles;
}


}


LogDBHelper代码

public class LogsDBHelper extends SQLiteOpenHelper {

//Application database name and version
private static final String DATABASE_NAME = "logs.db";
private static final int DATABASE_VERSION = 1;


public LogsDBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {

    // Database creation sql statement for oil table
    final String SQL_CREATE_OIL_TABLE = "CREATE TABLE "
            + OilTable.TABLE_NAME + "( "
            + OilTable.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + OilTable.COLUMN_DATE + " TEXT NOT NULL,"
            + OilTable.COLUMN_AMOUNT + " REAL NOT NULL,"
            + OilTable.COLUMN_MILES + " INTEGER NOT NULL);";

    // Database creation sql statement for coolant table
    final String SQL_CREATE_COOLANT_TABLE = "CREATE TABLE "
            + CoolantTable.TABLE_NAME + "( "
            + CoolantTable.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + CoolantTable.COLUMN_DATE + " TEXT NOT NULL,"
            + CoolantTable.COLUMN_AMOUNT + " REAL NOT NULL,"
            + CoolantTable.COLUMN_MILES + " INTEGER NOT NULL);";

    //Create the tables in the database
    db.execSQL(SQL_CREATE_OIL_TABLE);
    db.execSQL(SQL_CREATE_COOLANT_TABLE);

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS "+ OilTable.TABLE_NAME);
    db.execSQL("DROP TABLE IF EXISTS "+ CoolantTable.TABLE_NAME);
    onCreate(db);

}

}


更新#1:

在弄乱并调试了几个小时后,我发现,当我向表中添加新数据项,然后尝试删除该新添加的项时,它认为它的ID为0 ...但是应该不会。

例:
我的表中有1个数据项。它的数据行看起来像
ID:1,数据:“示例数据1”

现在,如果我将另一个数据项添加到该表中,
ID:1,数据:“示例数据1”
ID:2,数据:“示例数据2”

如果我要在插入数据后立即删除第二个数据项。我的删除查询认为我正在寻找ID:0,所以找不到它,也没有删除它。很有道理....但是如果我有我的原著

ID:1,数据:“示例数据1”

然后添加第二个数据项,现在看起来像这样
ID:1,数据:“示例数据1”
ID:2,数据:“示例数据2”

然后按返回按钮返回我的主活动...然后回到我的日志活动以尝试删除数据项2,删除查询将找到ID = 2并删除正确的数据项

就像我的ID自动递增的ID号没有提交一样,除非我退出并返回然后找到它。

更新#2:

解决了

问题出在我的Tab片段的Add方法中...在将数据插入表中之后,我从未使用它的新ID更新Log对象。

Log log = new Log();
Needed to set ID before adding it to mAdapter
log.setmDate(date);
log.setmAmount(amount);
log.setmMiles(miles);

mDataSource.insert(date, amount, miles, OilTable.TAG);

log.setmId(mDataSource.getLastLogID(OilTable.TAG));

mAdapter.add(log);

最佳答案

解决了

问题出在我的Tab片段的Add方法中...在将数据插入表中之后,我从未使用它的新ID更新Log对象。

Log log = new Log();
Needed to set ID before adding it to mAdapter
log.setmDate(date);
log.setmAmount(amount);
log.setmMiles(miles);

mDataSource.insert(date, amount, miles, OilTable.TAG);

log.setmId(mDataSource.getLastLogID(OilTable.TAG));

mAdapter.add(log);


没有它,查询中的ID将无法访问任何最近添加的数据,因为我正在引用我的Logs的ListView来获取要编辑和删除的Log信息。一旦我外出并重新加载到Log Activity中,它就可以正常工作,因为ListAdapter会填充包括ID在内的完整数据。

关于java - Android SQLite数据库未完全提交?更改直到 Activity 结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33945917/

相关文章:

java - 对象实例的全局观察

java - 为 toString() 格式的输出重载或覆盖 int method() ?

android - 使用registerReceiver动态注册C2DM接收器

java - Android-IllegalStateException : could not execute method of the activity

android - SQLite 数据库查询非常慢(SQLite Asset Helper)

java - 尝试使用 maven 从命令行运行 Java7 Hello World 项目

php - 尝试制作 Android 服务

android - 如何在 Dialog 中使用数据绑定(bind)?

java - 在 Android 中,为什么 SQLite 数据库不更新?

java - Spring 网 : Getting file from web context using Resource?