¿Cuál es el propósito de un mapa de proyección de Android en un proveedor de contenido?

Estoy viendo el código de ejemplo de la aplicación de bloc de notas Android en <path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad .

Me preguntaba si alguien podría explicarme por qué el siguiente código es necesario en NotepadProvider.java ?

 // Creates a new projection map instance. The map returns a column name // given a string. The two are usually equal. sNotesProjectionMap = new HashMap<String, String>(); // Maps the string "_ID" to the column name "_ID" sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID); // Maps "title" to "title" sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_TITLE,NotePad.Notes.COLUMN_NAME_TITLE); // Maps "note" to "note" sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE); // Maps "created" to "created" sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, NotePad.Notes.COLUMN_NAME_CREATE_DATE); // Maps "modified" to "modified" sNotesProjectionMap.put( NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE) 

Observo que el mapa de proyección se utiliza más adelante en el método query() :

 ... SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(NotePad.Notes.TABLE_NAME); /** * Choose the projection and adjust the "where" clause based on URI pattern-matching. */ switch (sUriMatcher.match(uri)) { // If the incoming URI is for notes, chooses the Notes projection case NOTES: qb.setProjectionMap(sNotesProjectionMap); break; ... 

¿Por qué se necesita este mapa de proyección?

La aplicación Notepad de las demostraciones de SDK es una aplicación de ejemplo, que debería ser un ejemplo de uso de API y buenas prácticas que utilizan esas API, por eso es probable que utilicen un mapa de proyección. Aunque la muestra del Notepad realmente no necesita un mapa de proyección, el uso de uno es un buen escaparate para casos más complejos cuando uno es necesario. Por ejemplo, si recuerdo bien, la aplicación de Shelves escrita por uno de los ingenieros de Google está usando un mapa de proyección en su ContentProvider y ese mapa de proyección no es sólo una asignación simple con pares clave-valor idénticos.

También he añadido un enlace a la documentación del método SQLiteQueryBuilder.setProjectionMap que tiene algunos detalles sobre por qué se necesita un mapa de proyección.

Su propósito principal es renombrar los nombres de columna encontrados en un cursor producido por una consulta.

@static declaration

 SEARCH_PROJECTION_MAP = new HashMap<String, String>(); SEARCH_PROJECTION_MAP.put( OpenHelper.NAME, OpenHelper.NAME + " as _name" ); SEARCH_PROJECTION_MAP.put( OpenHelper.ID , OpenHelper.ID + " as _id" ); 

@ Su funcionalidad de consulta

 //if you query using sqliteQueryBuilder then sqLiteQueryBuilder.setProjectionMap( SEARCH_PROJECTION_MAP ); //example if you just query Cursor cursor = sqLiteQueryBuilder.query( db, projection, selection, selectionArgs, null, null, sortOrder ); 

Las columnas devueltas ahora son _name y _id en este ejemplo.

Además de lo que dijo Juan, el propósito del mapa de proyección es para cambiar el nombre de las columnas, así como desambiguar los nombres de las columnas al hacer las uniones, el propósito importante de los mapas de proyección es verificar la selección contra los argumentos maliciosos.

Cuando se utiliza SQLiteQueryBuilder para crear una sentencia utilizando buildQueryString(boolean, String, String[], String, String, String, String, String) , si se especifica un mapa de proyección, los campos que no estén en ese mapa serán ignorados.

Para obtener la máxima protección contra aplicaciones de terceros maliciosas (por ejemplo, los proveedores de proveedores de contenido), puede hacer lo siguiente:

  1. Establecer SQLiteQueryBuilder#setStrict(true)
  2. Utilice un mapa de proyección.
  3. Utilice una de las sobrecargas de consulta en lugar de obtener la sentencia como una cadena SQL

Tal vez alguien necesita una explicación más completa. He reunido datos importantes sobre el mapa de proyección:

  1. Si no necesita un mapa de proyección, no lo configure. De esta manera, los nombres de las proyecciones se procesan "tal cual", exactamente como se pasa a través de la matriz de proyección.

  2. Incluso la matriz de proyección es opcional. Si pasa null a la consulta, genera una operación "SELECT *". (En realidad eso no se recomienda en SQL, debido a la rotura que puede ocurrir si las columnas se agregan / quitan o vuelven a ordenar).

  3. El mapa de proyección suministrado sólo se aplica a la lista de selección. Por lo tanto, podría asignar "store_name" => "bookstore.storename", y resultaría en "select bookstore.storename …", pero si proporcionó "store_name" en el parámetro "order by" o uno de Los otros parámetros calificados, potencialmente puede terminar con SQL mal.

  4. El mapa de proyección puede ser anulado. Si la parte clave de una entrada de proyección contiene una cláusula "as", la parte de valor se ignora y la parte clave se inserta en el SQL resultante. Por ejemplo "loro como polly" => "cracker" generará "SELECT loro como polly …" y no "cracker". El "como" puede ser en mayúsculas o en minúsculas (no en caso mixto) y debe tener al menos un espacio antes y después de la palabra "como".

Lea más información en este artículo: http://www.mousetech.com/blog/android-projection-maps-explained/

  • Android: contacto de búsqueda basado en número de teléfono
  • Cómo probar la actualización de la base de datos sqlite antes de cargar la nueva versión de mi aplicación en la tienda de juegos en android
  • ¿Es necesario tener acceso a una base de datos SQLite en un AsyncTask?
  • No se puede establecer la codificación de SQLiteDatabase en nada que no sea UTF-8
  • Almacenamiento de archivos de audio en una base de datos
  • Acceso a DB con diferentes contextos
  • Cómo ver la base de datos de aplicación de Android que se ejecuta en mi teléfono
  • Android: ¿Cómo importar el contacto desde el teléfono?
  • Android SQLite COMO comodín de escape
  • Android SQLiteOpenHelper - clase diferente para cada tabla?
  • Cómo comprobar la base de datos en el dispositivo Android no enraizada
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.