2012-10-04 12 views
7

Desidero solo una singola notifica dopo che tutto l'inserimento di massa è stato effettuato nel database. Si prega di fornire un esempio per utilizzare la funzione bulkInsert(). Non riesco a trovare un esempio corretto su internet. Per favore aiuto!!!!Come utilizzare la funzione bulkInsert() in Android?

risposta

37

Questo è bulkInsert tramite ContentProvider.

public int bulkInsert(Uri uri, ContentValues[] values){ 
    int numInserted = 0; 
    String table; 

    int uriType = sURIMatcher.match(uri); 

    switch (uriType) { 
    case PEOPLE: 
     table = TABLE_PEOPLE; 
     break; 
    } 
    SQLiteDatabase sqlDB = database.getWritableDatabase(); 
    sqlDB.beginTransaction(); 
    try { 
     for (ContentValues cv : values) { 
      long newID = sqlDB.insertOrThrow(table, null, cv); 
      if (newID <= 0) { 
       throw new SQLException("Failed to insert row into " + uri); 
      } 
     } 
     sqlDB.setTransactionSuccessful(); 
     getContext().getContentResolver().notifyChange(uri, null); 
     numInserted = values.length; 
    } finally {   
     sqlDB.endTransaction(); 
    } 
    return numInserted; 
} 

chiamata solo una volta quando si avrà più contentValues ​​in contentValues ​​[] valori array.

+0

Questo * not * termina gli inserimenti rimanenti se uno non funziona correttamente? – Anthony

+0

Questo ripristinerà/rollback ogni singolo inserimento se c'è qualche eccezione prima di chiamare setTransactionSuccessful in quel blocco try/catch. In breve, se c'è un'eccezione non otterrai alcun inserto. – Warlock

+0

Ho ricevuto un errore che diceva che "Variabile" tabella "potrebbe non essere stata inizializzata". Impostando la dichiarazione su 'String table =" ";' risolto il problema. –

3

Ho cercato per sempre di trovare un tutorial per implementarlo sul lato attività e sul lato fornitore di contenuti. Ho usato la risposta di "Warlock" dall'alto e ha funzionato benissimo sul lato del content provider. Ho usato la risposta da this post per preparare l'array ContentValues ​​alla fine dell'attività. Ho anche modificato i miei ContentValues ​​per ricevere da una stringa di valori separati da virgole (o nuove righe, punti, semi-punti). Che si presentava così:

ContentValues[] bulkToInsert; 
    List<ContentValues>mValueList = new ArrayList<ContentValues>(); 

    String regexp = "[,;.\\n]+"; // delimiters without space or tab 
    //String regexp = "[\\s,;.\\n\\t]+"; // delimiters with space and tab 
    List<String> splitStrings = Arrays.asList(stringToSplit.split(regexp)); 

    for (String temp : splitStrings) { 
     Log.d("current student name being put: ", temp); 
     ContentValues mNewValues = new ContentValues(); 
     mNewValues.put(Contract.KEY_STUDENT_NAME, temp); 
     mNewValues.put(Contract.KEY_GROUP_ID, group_id); 
     mValueList.add(mNewValues); 
    } 
    bulkToInsert = new ContentValues[mValueList.size()]; 
    mValueList.toArray(bulkToInsert); 
    getActivity().getContentResolver().bulkInsert(Contract.STUDENTS_CONTENT_URI, bulkToInsert); 

non riuscivo a trovare un modo più pulito per fissare la stringa divisa delineata dritto alla matrice contentValues ​​per bulkInsert. Ma funziona finché non lo trovo.

0

Prova questo approccio.

public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { 
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 

    switch (sUriMatcher.match(uri)) { 

     case CODE_WEATHER: 
      db.beginTransaction(); 
      int rowsInserted = 0; 
      try { 
       for (ContentValues value : values) { 


        long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, value); 
        if (_id != -1) { 
         rowsInserted++; 
        } 
       } 
       db.setTransactionSuccessful(); 
      } finally { 
       db.endTransaction(); 
      } 

      if (rowsInserted > 0) { 
       getContext().getContentResolver().notifyChange(uri, null); 
      } 


      return rowsInserted; 

     default: 
      return super.bulkInsert(uri, values); 
    } 
} 

La risposta di Warlock inserisce tutte o nessuna riga. Inoltre, eseguire attività minime tra setTransactionSuccessful() e endTransaction() e, naturalmente, nessuna operazione di database tra queste due chiamate di funzione.

Codice sorgente: Udacity

Problemi correlati