Alo*_*ini 8 java reflection android class
在我们的项目中,我们使用数据模型来存储从服务接收的数据.因此,在我们将数据插入数据库的特定情况下,我们使用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
}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
从今天早上起我就在努力解决这个问题.这是由于Android Studio 2的新功能,即即时运行,它在某个地方添加了这个字段,因为它可以在调试时看到:它实现了界面com.android.tools.fd.runtime.IncrementalChange.
可以通过使用isSynthetic()方法检查字段来解决此问题:它将返回true运行时生成的字段$change,false否则.