Android Java objModelClass.getClass().getDeclaredFields()返回$更改“;作为一个领域

Android Java objModelClass.getClass().getDeclaredFields()返回$更改“;作为一个领域,java,android,class,reflection,Java,Android,Class,Reflection,在我们的项目中,我们使用数据模型来存储从服务接收的数据。因此,在向数据库插入数据的特定情况下,我们使用objModelClass.getClass().getDeclaredFields()方法获取所有字段名,它正确地返回了类的所有字段名,但也返回了一个名为“$change”的额外字段,该字段在类中不存在 奇怪的是,在android studio中并没有这样的问题,但当我们升级到android studio 2.0时,这就发生了 虽然我已经应用了快速修复,但我需要正确地修复此问题。 我想知道为什

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

奇怪的是,在android studio中并没有这样的问题,但当我们升级到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
        }
    }
public void insertValuesIntoTable(最终字符串strTableName,ArrayList alObjClasses,
字符串strPrimaryKey、字符串strCompositeKey){
试一试{
SQLiteDatabase db_w=this.getWritableDatabase();
ContentValues ContentValues=新ContentValues();
//迭代ArrayList中的每个模型类对象,并将内容传输到DB
if(alObjClasses!=null)
对于(对象objModelClass:AlobjClass){
for(字段:objModelClass.getClass().getDeclaredFields()){
//如果启用了加密,则加密值&列将被加密
试一试{
字段。setAccessible(true);
//测试接收到的表格是否为“忽略联系人”。插入小黑客
//这样就可以重复使用相同的联系人数据模型
//表是否为忽略常量,然后检查该列是否存在
//是否与字段名的字段名相同。执行此操作将保存
//接收到一个SQLConstraint异常,声明“未找到列”
if(field.getName().equals(“$change”))
继续;
if(strTableName.equalsIgnoreCase(ContactConstants.TABLE_忽略_CONTACTS))
if(!field.getName().equalsIgnoreCase(ContactConstants.TABLE\u被忽略\u CONTACTS\u名称)
&&!field.getName().equalsIgnoreCase(ContactConstants.表\u忽略\u联系人\u号码)
&&!field.getName().equalsIgnoreCase(ContactConstants.TABLE\u忽略\u CONTACTS\u EMAIL)
&&!field.getName().equalsIgnoreCase(ContactConstants.TABLE\u已忽略\u CONTACTS\u CITY)
&&!field.getName().equalsIgnoreCase(ContactConstants.TABLE\u忽略\u CONTACTS\u ID))
继续;
contentValues.put(field.getName(),
(Constants.ENCRYPTION_首选项和&HelperFunctions.IsColumEncrypted(field.getName()))
?HelperFunctions.encryptString((字符串)字段.get(objModelClass))
:(String)field.get(objModelClass));
}捕获(非法访问例外e){
//e.printStackTrace();
//从不抛出,因为在访问数据之前调用了field.setAccessible(true);函数
}
catch(ClassCastException e){
//e.printStackTrace();
//从不抛出,因为在访问数据之前调用了field.setAccessible(true);函数
}
}
试一试{
if(db_w.insert(strTableName,null,contentValues)=-1)
抛出新的SQLiteConstraintException();
}捕获(SQLITE){
//e.printStackTrace();
Log.i(“Error-DB”,“尝试向中添加数据时出错”
+strTableName+“表,改为更新数据。”);
//由于该条目存在于数据库中,因此将对其进行更新
UpdateEntryDatabase(数据库、strTableName、strPrimaryKey、strCompositeKey、contentValues);
}
}
db_w.close();
}捕获(NullPointerException e){
//e.printStackTrace();
//有时在调用它的活动的上下文在执行过程中被销毁时引发
}
catch(sqlitee异常){
//e.printStackTrace();
//有时在调用它的活动的上下文在执行过程中被销毁时引发
}
}

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

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

我想知道为什么会这样

您的项目已在Android Studio 2.0之前构建,因此不准备使用Android Studio 2.0中引入的即时运行

我需要把它修好

您可以使用以下方法解决此问题:运行>清理并重新运行,来源:

或通过:

  • 禁用即时运行:文件>设置>生成、执行、部署>即时运行和 取消选中启用即时运行
  • 运行项目
  • 启用即时运行:文件>设置>生成、执行、部署