Android Java objModelClass.getClass (). GetDeclaredFields () devuelve "$ change" como un campo
En nuestro proyecto estamos utilizando modelos de datos para almacenar los datos recibidos de los servicios. Así que en un caso particular cuando estamos insertando datos en la base de datos, utilizamos el método objModelClass.getClass (). GetDeclaredFields () para obtener todos los nombres de campo y devuelve correctamente todos los nombres de campo de la clase pero también devuelve un campo extra con nombre "$ Change", que no existe en la clase.
Lo extraño es, en el estudio de Android no había tal problema, pero cuando actualizamos a android studio 2.0 esto sucedió.
- Android: cambiar el campo final estático privado usando la reflexión de java
- Java Reflection - Obtener todos los nombres de variables de instancia de una clase
- Android getOnTouchListener con la versión del API> = 15
- Recuperación de una lista de clases de un paquete en un proyecto de Android
- Soporte de la clase Robolectric de Android. Cómo tener las referencias de la clase de biblioteca R desde el proyecto de aplicación
Aunque he aplicado una solución rápida, pero tengo que solucionar correctamente esto. Quiero saber el por qué está sucediendo?
Esta es la función que utiliza este método
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 } }
- Obtener "java.lang.reflect.InvocationTargetException" al intentar registrar receptor de difusión de apk incrustado
- Proguard y reflexión en Android
- Android: cómo codificar dependiendo de la versión de la API?
- Reglas de ProGuard para la reflexión de Kotlin
- Reflexión de Java que maneja cambios de la biblioteca
- ¿Se puede usar la reflexión con métodos que pertenecen a un sdk mayor que el mínimo?
- Confirmación de mi comprensión del principio de Android Concept (uso de múltiples actividades)
- ¿Cómo utilizar la reflexión para cambiar el servicio de copia de seguridad?
Estoy luchando con este tema desde esta mañana. Es debido a la nueva funcionalidad de Android Studio 2, Instant run, que agrega este campo en alguna parte, como puede verse durante la depuración: implementa la interfaz com.android.tools.fd.runtime.IncrementalChange
.
Este problema puede resolverse comprobando el campo usando el método isSynthetic()
: devolverá true
para los campos generados por el runtime como $change
y false
caso contrario.
Quiero saber el por qué está sucediendo?
Su proyecto ya está construido en Android Studio antes de 2.0, por lo que no está preparado para usar la ejecución instantánea introducida en Android Studio 2.0
Necesito arreglar esto correctamente
Puede resolver el problema con: Ejecutar> Limpiar y volver a ejecutar, fuente: https://developer.android.com/studio/run/index.html#rerun
o por:
- Desactivar ejecución instantánea: Archivo> Configuración> Construir, Ejecución, Implementación> Ejecutar instantáneamente y desmarque Habilitar ejecución instantánea
- Ejecutar el proyecto
- Habilitar ejecución instantánea: Archivo> Configuración> Crear, ejecución, implementación> Ejecutar instantáneamente y active Habilitar ejecución instantánea