Forma / orden recomendada para leer datos de un servicio web, analizar esos datos e insertarlos en un SQLite db

Soy uno de los primeros en mencionar que soy totalmente nuevo en Android, acabo de leer un libro introductorio rápido y ahora tengo que implementar mi primera aplicación. Esta aplicación se usará para tomar pedidos. Entre todos los datos que voy a almacenar en una base de datos local, dos tablas son las más importantes: Clientes y artículos, siendo esta última la más grande de todas las tablas (aproximadamente 20000 registros) Uno de los principales procesos en mi aplicación, recupera todos los datos que mi aplicación necesita para trabajar fuera de línea cuando el usuario presiona un botón que inicia las operaciones diarias en el dispositivo.

Bueno, el proceso consiste en los siguientes pasos:

a. Lea un servicio tranquilo para recuperar los datos de los clientes
segundo. Analizar la respuesta a Json Objects
do. Inserte esos clientes en la Tabla de Clientes
re. Lea un servicio tranquilo para recuperar los datos de artículos
mi. Analizar la respuesta a Json Objects
F. Inserte esos artículos en la Tabla de artículos

Esto es lo que he planeado hacer:

  1. Escriba una clase auxiliar que maneje todas las solicitudes HTTP GET. Luego llame a esta clase cuando necesite descargar todos los datos de Clientes y Artículos
  2. Como todo este proceso puede llevar mucho tiempo, necesito hacerlo de fondo. Entonces, según algunas sugerencias, voy a poner todo este código dentro de un Bound Service.
  3. Mientras que todo este proceso largo se lleva a cabo en el fondo, tendré que mostrar algún tipo de indicador (un ProgressDialog) Esta es la razón por la que opté por usar un Bound Service

Aunque creo que tengo la idea general de cómo hacer la mayor parte de estas cosas por separado , creo que armar el conjunto es una historia bastante diferente.

Así que estas son las preguntas que tengo ahora que tengo que armar el rompecabezas:

  1. ¿Crees que el orden en el que estoy ejecutando los 6 pasos del proceso descrito es correcto / eficiente? Si tuviera que hacer algunos cambios, ¿qué cambiaría?
  2. Si la actividad que inició el servicio se cancela explícitamente o está oculta por otra actividad, el servicio debe contar con una manera de informar al usuario que el proceso ha finalizado. ¿Cómo podría implementar eso?
  3. ¿Es posible / recomendable escribir en la base de datos SQLite dentro del servicio? ¿Es lo mismo que cuando lo hago dentro de una actividad?
  4. En J2ME hice algo similar, y cuando puse algo como los 6 pasos que mencioné anteriormente, todos se ejecutan secuencialmente, es decir, uno después del otro. ¿Es lo mismo en Android?

Espero no estar haciendo demasiadas preguntas. Los puse juntos porque están relacionados.

Básicamente en esta pregunta no estoy pidiendo código de trabajo (aunque estaría bien si pudieras proporcionar algún código de muestra) Lo que realmente estoy buscando son algunas sugerencias, alguna guía. Algo así como “Oye, creo que esto podría ayudarte con el punto número 3” o “Quizás encuentres útil este artículo” , “Creo que será mejor que uses esto en lugar de eso” . Ese tipo de cosas.

Decidí acudir a ustedes porque ustedes son los expertos y realmente necesito que alguien me ponga en la dirección correcta.

Muchas gracias.

PD. Por favor, no cierres esta pregunta, si crees que necesito cambiar algo solo házmelo saber y lo haré.

Decidí ir a verlos porque son los expertos

primero i am not expert y tampoco i am not knowledgeable gente más experta que yo, pero esta es mi opinión, hope to give you some help .

en primer lugar, olvide utilizar AsyncTask para descargar, ya que debe usarse para trabajos de fondo cortos, no como los suyos, creo que la cantidad de archivos que desea descargar es bastante grande. (Creo que sí)

revise downloadmanager of google para ver cómo funciona, puede ayudarle.

http://developer.android.com/reference/android/app/DownloadManager.html

http://blog.vogella.com/2011/06/14/android-downloadmanager-example/

Si desea utilizar el service use el service unbound service porque no desea que el servicio sea destruido por Android o por el usuario cuando el usuario cierra las aplicaciones, ¿verdad? Creo que quiere obtener sus datos de cualquier manera.

Para ser eficiente, recomiendo estos pasos:

a. Lea un servicio tranquilo para recuperar los datos de los clientes

segundo. cuando obtienes datos del cliente hazlo:

  • crear otro servicio o hilo para leer un servicio tranquilo para recuperar los datos de artículos

  • Analiza la respuesta a Json Objects en tu antiguo servicio o hilo

ahora tiene 2 servicios o subprocesos que se ejecutan al mismo tiempo, siga los pasos que obviamente insert parse y así sucesivamente, en cada servicio o subproceso.

¿Por qué no combino a y d? porque creo que al usuario no le gusta esperar mucho tiempo detrás de la barra de progreso de la descarga.

para insertar tus datos en la transaction uso de la base de datos y te recomiendo que uses:

http://greendao-orm.com/

es ORM más eficiente que otros para la base de datos y se libera de la implementación de db.

Si la actividad que inició el servicio se cancela explícitamente o está oculta por otra actividad, el servicio debe contar con una manera de informar al usuario que el proceso ha finalizado. ¿Cómo podría implementar eso?

notificación de uso:

http://developer.android.com/training/notify-user/build-notification.html

http://www.tutorialspoint.com/android/android_notifications.htm

http://www.vogella.com/tutorials/AndroidNotifications/article.html

Mientras que todo este proceso largo se lleva a cabo en el fondo, tendré que mostrar algún tipo de indicador (un ProgressDialog) Esta es la razón por la que opté por usar un Bound Service ‘.

¿Cómo puedo actualizar la UI de un servicio independiente?

Utilice LocalBroadCastManager , o en general BroadCastReciever

IU de actividad de actualización de Android del servicio

En J2ME hice algo similar, y cuando puse algo como los 6 pasos que mencioné anteriormente, todos se ejecutan secuencialmente, es decir, uno después del otro. ¿Es lo mismo en Android?

esto depende de tus pasos, si sigues mi idea de que ejecutas al concurrently y si ejecutas tu idea, se ejecutará sequentially .

Buena suerte.

Hice algo como el tuyo.

En el primer paso obtengo datos del servicio webservice en HTTP GET del método POST usando AsyncTask esta manera:

 public class GetService extends AsyncTask { private String mRestUrl; private ServiceCallback mCallback; private final HttpClient Client = new DefaultHttpClient(); private String Content; private String url; private String Error; private ProgressDialog barProgressDialog; private ProgressDialog Dialog; public GetService(String restUrl, ServiceCallback callback) { this.mRestUrl = restUrl; this.mCallback = callback; this.url = restUrl; Dialog = new ProgressDialog(AppContext.CurrentContext); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... urls) { Content = null; BufferedReader reader = null; try { StringBuilder builder = new StringBuilder(); HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(this.url); HttpResponse response = client.execute(get); int status = response.getStatusLine().getStatusCode(); if (status == 200) // sucess { HttpEntity e = response.getEntity(); // String data = EntityUtils.toString(e); InputStream content = e.getContent(); reader = new BufferedReader(new InputStreamReader(content)); String line; while ((line = reader.readLine()) != null) { builder.append(line); } Content = builder.toString(); } else if (status == 401) { return "-Auth Failed Error Code 400"; } else { return "-Error Code: " + status; } } catch (Exception ex) { Error = ex.getMessage(); } finally { Dialog.dismiss(); try { reader.close(); } catch (Exception ex) { ex.printStackTrace(); } } return Content; } @Override protected void onPostExecute(String result) { try { GetService.this.get(20000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } mCallback.onTaskComplete(result); super.onPostExecute(result); } } 

y mi clase de callback es:
clase abstracta pública ServiceCallback {

 public abstract void onTaskComplete(String result); } 

Llamo a AsyncTask en mi código donde quiera obtener datos del servicio web:

  new GetService(url, new ServiceCallback() { public void onTaskComplete(String response) { // Parse Response of WebService } }).execute(); 

En el segundo paso, analizo la respuesta de WebService en el método onTaskComplete usando json helper Libraries como Gson o Jackson . por ejemplo en jackson:

 List data = new ObjectMapper() .readValue( response, new TypeReference>() { }); 

Al final, almaceno datos en la base de datos. para conectarse a DB I Prefiero usar GreenDao como mi ORM. De esta forma, los datos storin en DB se pueden hacer en un código de línea como este:

 //after converting json to object YourORMDaoClass.insertOrReplaceInTx(data); 

Para usar GreenDao ORM, este enlace es muy útil;

¿Crees que el orden en el que estoy ejecutando los 6 pasos del proceso descrito es correcto / eficiente? Si tuviera que hacer algunos cambios, ¿qué cambiaría?

Depende. Si estos datos están relacionados y no pueden existir sin el otro, entonces debe cambiar el orden de esta manera:

 a. Read a restful service to retrieve the Customers Data b. Parse the response to Json Objects d. Read a restful service to retrieve the Articles Data e. Parse the response to Json Objects c. Insert those customers to the Customers Table f. Insert those articles to the Articles Table 

Los pasos c y f deben combinar en la transacción.

De lo contrario, el orden no importa. Si los datos no están relacionados, separar estos procesos y ejecutarlos en secuencia podría ser una buena idea.


Si la actividad que inició el servicio se cancela explícitamente o está oculta por otra actividad, el servicio debe contar con una manera de informar al usuario que el proceso ha finalizado. ¿Cómo podría implementar eso?

Sugiero comenzar con la implementación de la clase IntentService . Se encarga de tu hilo de fondo y funciona como una cola de eventos donde Single Intent entrega datos para procesar.

De hecho, podría implementar uno de los patrones presentados por Google en una de sus conferencias IO . Implementé una opción A en el video. Me funciona realmente bien. El truco es que usar ContentProvider desde el fondo actualiza automáticamente la interfaz de usuario que escucha los cambios gracias a CursorAdapter.

Para actualizar el progreso de UI, puede usar LocalBroadcastManager o bibliotecas de bus de eventos, por ejemplo, Otto .

También puede ampliar sus tablas y almacenar estado y progreso, la actualización de las tablas también actualizaría automáticamente la IU, solo tenga en cuenta que estas actualizaciones deben ser raras. Por ejemplo, controlar en el fondo del servicio la frecuencia con la que se actualiza la tabla calculando primero el progreso y verificando servicio de variable local si se cambia.

En caso de que su aplicación esté en segundo plano, envíe una notificación de estado. El usuario debería poder navegar de regreso a su aplicación haciendo clic en la notificación.


¿Es posible / recomendable escribir en la base de datos SQLite dentro del servicio? ¿Es lo mismo que cuando lo hago dentro de una actividad?

Puedes hacerlo dentro del Servicio. En realidad, si sigue el patrón que he mencionado anteriormente, lo haría en el nivel Procesador en el hilo de servicio en segundo plano.


En J2ME hice algo similar, y cuando puse algo como los 6 pasos que mencioné anteriormente, todos se ejecutan secuencialmente, es decir, uno después del otro. ¿Es lo mismo en Android?

Depende completamente de usted cómo funcionará la comunicación con el servidor. Si decides utilizar la clase IntentService , funcionará en una secuencia que no es mala idea para Android. Por otro lado, puede ampliar la clase de servicio directamente e implementar su propio ejecutor de subprocesos con un grupo de subprocesos. También puede tener clases dedicadas de IntentService para operaciones no relacionadas.


También recomiendo leer lecciones:

  • Transferencia de datos sin agotar la batería
  • Transferencia de datos utilizando adaptadores de sincronización

Si no quiere jugar directamente con la implementación de la conexión HTTP, considere usar Retrofit o Volley

Si solo necesitas los analizadores JSON, estos 2 son los mejores:

  • GSON
  • Jackson