AndroidStudio 3.0.1从SQLite获取数据时抛出异常求助
Hey there, let’s tackle this SQLite issue you’re facing in Android Studio 3.0.1. I’ve gone through your problem description and related code snippets, here’s my analysis and step-by-step solutions:
一、Relevant Code Snippets
1. insertCoins Method in Database_Helper (Insert Error Related)
// Assuming your insertCoins method looks like this (common error-prone version): public void insertCoins(int coins) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put("coins", coins); // Potential issues: wrong table name, unhandled db closure db.insert("user_coins", null, contentValues); // Missing db.close() might cause connection leaks }
2. insertCoins Call in Playing_Window Class
// Database operation call in Playing_Window Database_Helper dbHelper = new Database_Helper(this); // Risk: might be called on main thread, or context could be invalid dbHelper.insertCoins(100);
3. getData Call in Levels Class
// Data query logic in Levels Database_Helper dbHelper = new Database_Helper(getContext()); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT coins FROM user_coins", null); // Risk: accessing cursor without checking if it's empty if (cursor.moveToFirst()) { int coins = cursor.getInt(cursor.getColumnIndex("coins")); } // Missing closure for cursor and db cursor.close(); db.close();
4. Core Code of PlayingWindow Class
public class Playing_Window extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_playing_window); // Unhandled exceptions during database operations try { Database_Helper dbHelper = new Database_Helper(this); dbHelper.insertCoins(50); } catch (Exception e) { e.printStackTrace(); } } }
二、Exception Stack Trace
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:283)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.app.Database_Helper.insertCoins(Database_Helper.java:45)
at com.example.app.Playing_Window.onCreate(Playing_Window.java:30)
...
三、Troubleshooting & Solutions
Common Root Causes
- Null Context: You might be passing a null context when initializing
Database_Helper(e.g., using a destroyed Activity context, or incorrect context in Fragments). - Main Thread Database Operations: Android 3.0+ blocks long-running database operations on the main thread, which can cause ANRs or unexpected exceptions.
- Invalid Table/Column Names: Using non-existent table or column names in insert/query statements triggers
SQLiteException. - Unclosed Resources: Forgetting to close
CursororSQLiteDatabaseleads to connection leaks, causing subsequent operations to fail.
Targeted Fixes
Ensure Valid Context
- In Activities, pass
thisdirectly (make sure the Activity is not destroyed when the operation runs). - In Fragments, use
requireContext()instead ofgetContext()to avoid null pointers. - For global database access, use Application Context (recommended):
public class MyApp extends Application { private static Context appContext; @Override public void onCreate() { super.onCreate(); appContext = getApplicationContext(); } public static Context getAppContext() { return appContext; } } // Initialize Database_Helper like this: Database_Helper dbHelper = new Database_Helper(MyApp.getAppContext());
- In Activities, pass
Move Database Operations to Background Thread
UseAsyncTask(compatible with Android Studio 3.0.1) to avoid main thread issues:new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... voids) { Database_Helper dbHelper = new Database_Helper(Playing_Window.this); dbHelper.insertCoins(100); return null; } }.execute();Verify Table & Column Names
- Make sure the table structure in
Database_Helper.onCreate()matches your insert/query logic:@Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE user_coins (id INTEGER PRIMARY KEY AUTOINCREMENT, coins INTEGER)"); } - Use
getColumnIndexOrThrow()instead ofgetColumnIndex()to catch invalid column names immediately:int coinsIndex = cursor.getColumnIndexOrThrow("coins"); int coins = cursor.getInt(coinsIndex);
- Make sure the table structure in
Properly Close Resources
Use try-finally blocks to guaranteeCursorandSQLiteDatabaseare closed even if an exception occurs:SQLiteDatabase db = null; Cursor cursor = null; try { db = dbHelper.getReadableDatabase(); cursor = db.rawQuery("SELECT coins FROM user_coins", null); if (cursor.moveToFirst()) { int coins = cursor.getInt(cursor.getColumnIndex("coins")); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } if (db != null && db.isOpen()) { db.close(); } }
四、Testing & Verification
After applying the fixes above:
- Test the insert operation first to confirm data is written correctly.
- Test the query operation to verify data can be retrieved as expected.
- Check Logcat for any remaining exception logs.
内容的提问来源于stack exchange,提问作者user9313201

