Android钱包应用SQLite报错求助:Fragment加载与Cursor越界
Hey there! Let's break down the two errors you're hitting with your Android wallet app, and figure out what's causing them and how to fix them.
1. Fragment Inflation Failure (InflateException)
Error Recap
FATAL EXCEPTION: main Process: com.carrot.wallet, PID: 30591 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.carrot.wallet/com.carrot.wallet.MainActivity}: android.view.InflateException: Binary XML file line #10 in com.carrot.wallet:layout/activity_main: Binary XML file line #10 in com.carrot.wallet:layout/activity_main: Error inflating class fragment
What's Causing This
This error pops up when your app fails to load a Fragment while inflating the activity_main layout, and it's directly tied to your call to DatabaseHelper1.getRemainingAmount(). Here are the most likely culprits:
- Invalid Fragment Configuration: Line 10 of your
activity_main.xmlis a<fragment>tag. If you didn't specify the correctandroid:nameattribute (with the full path to your Fragment class, e.g.,com.carrot.wallet.YourWalletFragment), or there's a typo in the class name, the system can't find and instantiate the Fragment. - Bad Database Context in Fragment: If you're initializing
DatabaseHelper1inside the Fragment (like inonCreateVieworonCreate), you might be using a null or invalid Context (e.g.,getContext()instead ofrequireContext()). This breaks the database connection, and the exception thrown bygetRemainingAmount()interrupts the Fragment inflation process. - Early Database Calls: If you're calling
getRemainingAmount()too early in the Fragment/Activity lifecycle (before the UI is fully inflated, like inActivity.onCreateright beforesetContentView), the database operation can fail and crash the inflation flow.
Quick Fixes to Try
- Double-check line 10 of
activity_main.xml: Ensure the<fragment>tag has a correctandroid:namevalue pointing to your actual Fragment class. - Use a safe Context for
DatabaseHelper1: In Fragments, userequireContext()instead ofgetContext()to avoid nulls. In Activities, usethisdirectly. - Move database operations to a later lifecycle stage: Shift calls to
getRemainingAmount()toActivity.onStart()orFragment.onViewCreated()—this ensures the UI is ready and Context is valid. - Add error handling: Wrap the
getRemainingAmount()call in atry-catchblock to catch database exceptions, log details, and prevent the entire Fragment from crashing.
2. CursorIndexOutOfBoundsException
Error Recap
2020-05-30 09:25:12.946 11239-11239/com.carrot.wallet E/AndroidRuntime: FATAL EXCEPTION: main Process: com.carrot.wallet, PID: 11239 android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0 at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)...
What's Causing This
This is a straightforward issue: your database query returned an empty Cursor (size 0), but your code tried to access data from it without checking if there's anything to read. By default, a Cursor starts at index -1—if you call cursor.getInt(0) or cursor.getString(1) without first moving the cursor to a valid position (like the first row), you'll hit this error.
This usually happens when:
- Your database has no transaction records yet, so the query for remaining amount returns no results.
- Your SQL query is incorrect (e.g., filtering for non-existent data) and returns an empty result set.
- You forgot to call
cursor.moveToFirst()orcursor.moveToNext()before accessing Cursor data.
Quick Fixes to Try
- Always validate the Cursor first: Before accessing any data, check if the Cursor is not null and has rows. Here's a pattern to follow:
Cursor cursor = db.rawQuery("YOUR_QUERY", null); int remainingAmount = 0; // Default value if no data exists if (cursor != null && cursor.moveToFirst()) { // Get the value using the column name (safer than index) remainingAmount = cursor.getInt(cursor.getColumnIndex("remaining_amount")); cursor.close(); // Don't forget to close the Cursor to avoid leaks! } return remainingAmount; - Handle empty results in SQL: Modify your query to return a default value when there's no data. For example, if you're summing transactions, use
COALESCEto return 0 instead of null:SELECT COALESCE(SUM(amount), 0) AS remaining_amount FROM transactions - Debug your query: Log the SQL statement you're running and check if it returns expected results when the database is empty.
内容的提问来源于stack exchange,提问作者Apoorv Srivastava

