Android: Ampliación del libro de contactos del usuario. Rendimiento ContentProvider vs Sqlite vs Lista en la memoria

Yo y mi equipo de Android tenemos un problema. Tenemos una aplicación que presenta el libro de contactos del usuario, con información ampliada.

Configuración actual

Nuestra aplicación lee el proveedor de contactos del sistema operativo Android. Envía esta información a nuestro servidor que calcula un par de campos necesarios para nosotros. Esta información es obtenida más tarde por nuestra aplicación y guardamos esta información en una base de datos SQLite. Lo que acabamos en nuestra base de datos son dos tablas. Uno con todos los números y toda la información adicional que el servidor calculó para nosotros. La otra tabla es una con todos los contactos (un contacto puede tener varios números). Esta tabla de contactos se creó sólo para el rendimiento; Podemos tener un Cursor seleccionando todas las filas en esta tabla de Contactos en nuestro CursorAdapter al presentar el libro de contactos para el usuario. Por lo tanto, al presentar el libro de contactos al usuario, sólo necesitamos leer de nuestra propia base de datos SQLite y sólo una tabla (por ejemplo, no JOIN).

El problema principal

Hay un montón de sincronización en curso. Dado que, los datos se duplican, necesitamos comprobar si hay añadidos / cambios / eliminados y es necesario sincronizar todo el tiempo f-ing. Por otra parte, cuando ahora estamos a punto de cambiar una cosa particular en nuestra capa de la presentación, necesitamos cambiar nuestra tabla de los contactos para incluir esta información particular.

Prioridad para nosotros

1er: Rendimiento al presentar el libro de contactos al usuario.

2º: Mantenibilidad del código.

Por lo tanto, no comentar "No duplicar los datos – es la raíz de todos los problemas". Es más importante para nosotros que el usuario no tiene problemas de rendimiento que si nosotros, como desarrolladores, tenemos que dedicar más tiempo escribiendo buenos algoritmos de sincronización.

Soluciones?

No sé por qué, pero siempre he pensado que un CursorAdapter (lectura de todas las filas de una tabla) está realizando mucho mejor que un ArrayAdapter con una lista de objetos (almacenados en la memoria). alguien sabe si esto es verdad? Debido a que una solución que nos ayudará al menos a mitad de camino es, al iniciar, unirse al proveedor de contactos (libro de contacto nativo) y nuestra información extendida, guardar esto en una lista en la memoria y presentar esto con un ArrayAdapter.

¿Creando sus propios proveedores de contenido? Sé poco sobre la creación de su propio proveedor de contenido. Cualquier persona trató de crear un proveedor de contenido que ampliar la información del libro de contacto nativo y unirse a ellos. Tal vez con la implementación de esta interfaz: ContactsContract.DataColumnsWithJoins? ¿Alguien intentó algo similar? ¿Cómo es el rendimiento al presentar esta información en un CursorAdapter?

Por favor, pida más información que podría haber olvidado y voy a actualizar la pregunta!

Muchas gracias por adelantado por todos los consejos útiles y soluciones!

He llegado a la conclusión (trabajando en mi aplicación JReader que se basa en operaciones de DB rápido mucho) que SQLite en Android es bastante rápido como en otras plataformas, pero hay algunos problemas específicos de Android. Algunos consejos sobre el rendimiento de la base de datos y las preguntas que ha hecho:

  • Los proveedores de contenido son en su mayoría inútiles si usted no está planeando compartir sus datos a través de ellos. Pero proporcionan al menos dos ventajas. Primero obtienes notificaciones de cambio de datos y el cursor se actualiza automáticamente, y el segundo e importante: CursorLoaders requiere un proveedor de contenido, y si el rendimiento es importante para ti, te recomiendo que los uses para cargar el cursor;
  • El acceso a las colecciones es mucho más rápido que el acceso a la base de datos, pero es un trabajo doble, ya que tiene que persistir los datos de todos modos, y el acceso a la base de datos es bastante rápido, incluso para la recopilación de datos para una lista de desplazamiento súper rápido y, No debe ser un problema;
  • Diseñe su DB correctamente (con JOINS, índices, etc) 🙂 PERO NO USAR JOIN QUERIES EN CURSOR QUERIES! He tenido muchos problemas de rendimiento con eso en varias plataformas Android (incluyendo 4.0 +), aunque no siempre. La forma de acceso a las mesas conjuntas es simplemente obtener la clave extranjera primero y luego consultar la tabla hijo.

En mi experiencia, he tenido las situaciones cuando el desempeño de DB fue muy pobre, pero al final siempre he logrado ajustar el código y, como resultado, aumentaría el rendimiento de 10 a 100 veces. Así que seguir perfilando código de DB, y sin duda va a lograr el rendimiento deseado.

El segundo comentario de Dan es cierto .. Android utiliza la ventana de cursor debajo de las pantallas para almacenar en caché los datos del cursor (aproximadamente 1M). Vea Documentos de Android en la ventana del cursor , que es cómo el adaptador de cursor es más rápido.

Si no prefieres unir dos tablas separadamente, podrías considerar un CursorJoiner que sea más rápido, Esto puede ir a tu contenido personalizado donde uno de los proveedores está apuntando a los Contactos y devuelve un Cursor, similarmente el segundo apunta a tu propia tabla y Devuelve un cursor. El cursorjoiner puede unir ambos cursores.

(Aunque es un proceso complicado)

  • Diferencia entre las funciones window.openDatabase () y window.sqlitePlugin.openDatabase ()?
  • Cómo convertir de java.util.HashMap a android.content.ContentValues?
  • Cómo extraer el cursor y el valor entero de una matriz de clase Object
  • ¿Cómo comprobar si existe una tabla en Android?
  • Cursor finalizado sin cerrar antes () en ListFragment
  • Inserción masiva en un dispositivo Android
  • SQLite selecciona todos los registros de hoy y día anterior
  • Diferencias de rendimiento entre SQLite en Android e iOS
  • ¿Cómo puedo ordenar mi base de datos SQLITE en orden descendente, para una aplicación de Android?
  • cómo importar. sqlite en la base de datos en sqlite en android
  • ¿Qué pasa con multithreading en Android SQLite?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.