2016-04-11 6 views
7

Nel nostro progetto utilizziamo modelli di dati per archiviare i dati ricevuti dai servizi. Quindi, in un caso particolare quando inseriamo i dati nel database, utilizziamo il metodo objModelClass.getClass(). GetDeclaredFields() per ottenere tutti i nomi dei campi e restituisce correttamente tutti i nomi dei campi della classe, ma restituisce anche un campo in più con il nome "$ change", che non esiste nella classe.

La cosa strana è che, in Android Studio, non ci sono stati problemi di questo tipo, ma quando siamo passati ad Android Studio 2.0 è successo.

Anche se ho applicato una soluzione rapida, ma ho bisogno di correggere correttamente questo. Voglio sapere perché sta succedendo?

Questa funzione utilizzando questo metodo

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

Il mio problema è che l'elemento su 0 è "$ change" e l'articolo su 48 è "serialversionuid" ..... Quando vedo cosa restituisce il lungo dai campi [ 48] .getLong (nullo). foo [47] .getlong = 2.131.099,695 mila foo [48] = 0 .getlong foo [49] .getlong = 2.131.099,696 mila Molto perplessi su quello che potrebbe causare questo. – Zypps987

+0

puoi inserire del codice, per maggiore chiarezza? nel frattempo se il tuo problema è uguale al mio, controlla le soluzioni fornite di seguito. –

risposta

10

sto lottando con questo problema da questa mattina. È dovuto alla nuova funzionalità di Android Studio 2, Instant run, che aggiunge questo campo da qualche parte, come può essere visto durante il debugging: implementa l'interfaccia com.android.tools.fd.runtime.IncrementalChange.

Questo problema può essere risolto selezionando il campo con il metodo isSynthetic(): tornerà true per campi generati dal runtime come $change e false altrimenti.

+1

Rilevante bug di Android qui: https://code.google.com/p/android/issues/detail?id=204714 - il campo '$ change' diventerà probabilmente transitorio in Android Studio 2.1, che risolverebbe gran parte dei problemi potrebbe produrre proprio ora. –

+0

@miles il problema era presente anche nel canale di anteprima di Android studio 1.8 (per quanto ricordo), e non aveva funzionalità di esecuzione istantanea o hotswapping, anche se controllerò se la tua soluzione funziona. grazie –

+0

@Kernald yea, penso che sarà risolto in una versione futura, ma fino ad allora è necessario avere una soluzione che non si romperà anche nelle versioni future. –

1

Voglio sapere perché sta succedendo?

Il progetto già realizzato in Android Studio precedenti alla 2.0 in modo che non è disposto a utilizzare Immediata run introdotto in Android Studio 2,0

ho bisogno di risolvere correttamente questo

È possibile risolvere il problema utilizzando: Esegui> Pulisci e riesegui, fonte: https://developer.android.com/studio/run/index.html#rerun

o da:

  1. Disabilita esecuzione istantanea: File> Impostazioni> Crea, esecuzione, distribuzione> Esegui istantanea e deselezionare Enable Run Immediata
  2. eseguire il progetto
  3. Attiva Instant Run: File> Impostazioni> Crea, Esecuzione, Deployment > Esegui istantaneo e seleziona Abilita esecuzione immediata
Problemi correlati