Android Java objModelClass.getClass (). GetDeclaredFields () returns "$ change" as a single field

In our project, we use data models to store data received from services. Therefore, in the specific case, when we insert data into the database, we use the objModelClass.getClass () method . GetDeclaredFields () to get all the field names and correctly return all the field names of the class, but also returning one additional field with the name "$ change" that does not exist in the class.

The strange thing: in android studio there was no such problem, but when we upgraded to the version for Android 2.0, it happened.

Although I applied a quick fix, I need to fix it correctly. I want to know why this is happening?

This function using this method

public void insertValuesIntoTable(final String strTableName, ArrayList<Object> alObjClasses, String strPrimaryKey, String strCompositeKey) { try { SQLiteDatabase db_w = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); //Iterate through every model class Object in the ArrayList and transfer the contents to the DB if (alObjClasses != null) for (Object objModelClass : alObjClasses) { for (Field field : objModelClass.getClass().getDeclaredFields()) { //Encrypt value if encryption is enabled & the column is to be encrypted try { field.setAccessible(true); //Test if the table received is Ignore contacts. Minor Hack inserted //So that the same contact data model can be re used. It checks if the //Table is of ignored constant or not then checks if the column exists //in the table or not as that of the field name. Doing this saves //from receiving a SQLConstraint exception stating, "Column not found" if(field.getName().equals("$change")) continue; if(strTableName.equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS)) if(!field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_NAMES) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_NUMBERS) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_EMAIL) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_CITY) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_ID)) continue; contentValues.put(field.getName(), (Constants.ENCRYPTION_PREFERENCE && HelperFunctions.isColumnEncrypted(field.getName())) ? HelperFunctions.encryptString((String) field.get(objModelClass)) : (String) field.get(objModelClass)); } catch (IllegalAccessException e) { // e.printStackTrace(); //Never thrown since field.setAccessible(true); is called before accessing data } catch ( ClassCastException e) { // e.printStackTrace(); //Never thrown since field.setAccessible(true); is called before accessing data } } try { if (db_w.insert(strTableName, null, contentValues) == -1) throw new SQLiteConstraintException(); } catch (SQLiteConstraintException e) { // e.printStackTrace(); Log.i("Error - DB", "Error occurred while trying to add data to " + strTableName + " Table, updating data instead."); //Since the entry exists in the DB, it will be updated instead updateEntryInDatabase(db_w, strTableName, strPrimaryKey, strCompositeKey, contentValues); } } db_w.close(); } catch (NullPointerException e) { // e.printStackTrace(); //Is thrown sometimes when the context of the activity which called it is destroyed mid execution } catch (SQLiteException e) { // e.printStackTrace(); //Is thrown sometimes when the context of the activity which called it is destroyed mid execution } } 
+7
java android reflection class
source share
2 answers

I struggle with this issue in the morning. This is thanks to the new functionality of Android Studio 2, Instant run, which adds this field somewhere, as seen during debugging: it implements the interface com.android.tools.fd.runtime.IncrementalChange .

This problem can be solved by checking the field using the isSynthetic() method: it will return true for the fields generated by the runtime, for example, $change and false otherwise.

+10
source share

I want to know why this is happening?

Your project has already been built in Android Studio prior to 2.0, so it is not ready to use the Instant run introduced in Android Studio 2.0

I need to fix it right

You can solve the problem using: Run> Clean and Rerun, source: https://developer.android.com/studio/run/index.html#rerun

or:

  • Disable instant start: File> Settings> Build, run, deploy> Instant start and uncheck Enable immediate start
  • start a project
  • Enable Instant Launch: File> Settings> Build, Run, Deploy> Instant Launch and Test Enable Instant Launch
+1
source share

All Articles