Android Java objModelClass.getClass().getDeclaredFields()返回“$change”作为一个字段

在我们的项目中,我们使用数据模型来存储从服务接收的数据.因此,在我们将数据插入数据库的特定情况下,我们使用objModelClass.getClass().getDeclaredFields()方法来获取所有字段名称,并且它正确地返回该类的所有字段名称,但也返回一个带有名称的额外字段“$change”,在课堂上不存在.

奇怪的是,在Android工作室中没有这样的问题但是当我们升级到android studio 2.0时就发生了这种情况.

虽然我已经应用了快速修复,但我需要正确解决这个问题.
我想知道它为什么会发生?

这个函数使用这个方法

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
        }
    }

解决方法

从今天早上起我就在努力解决这个问题.这是由于Android Studio 2的新功能,即Instant run,它在某个地方添加了这个字段,因为它可以在调试时看到:它实现了com.android.tools.fd.runtime.IncrementalChange接口.

这个问题可以通过使用isSynthetic()方法检查字段来解决:它将为运行时生成的字段返回true,如$change,否则返回false.

相关文章

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...