Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


ContentProvider insert () siempre se ejecuta en el hilo de interfaz de usuario?

Tengo una aplicación que necesita extraer datos de un servidor e insertarlo en una base de datos SQLite en respuesta a la entrada del usuario. Pensé que esto sería bastante simple – el código que extrae los datos del servidor es una subclase bastante simple de AsyncTask, y funciona exactamente como lo esperaba sin colgar el hilo de interfaz de usuario. Implementé la funcionalidad de devolución de llamada para ello con una interfaz sencilla y lo envolví en una clase estática, por lo que mi código se ve así:

MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() { @Override public void onFolderContentsResponse(final List<FilesystemEntry> contents) { // do something with contents } } 

Todo sigue siendo bueno. Incluso si el servidor tarda una hora en recuperar los datos, la interfaz de usuario se ejecuta sin problemas, porque el código de getFolderContents se ejecuta en el método doInBackground de un AsyncTask (que está en un subproceso separado de la interfaz de usuario). Al final del método getFolderContents, se llama a onFolderContentsResponse y se pasa la lista de FilesystemEntry que se recibió desde el servidor. Yo sólo digo todo esto para que sea esperanzadamente claro que mi problema no está en el método getFolderContents o en cualquiera de mi código de red, porque nunca ocurre allí.

  • No se pudo encontrar el contenedor gradle dentro de SDK de Android. Puede ser necesario actualizar su SDK de Android
  • Cómo liberar memoria en android para evitar fugas de memoria
  • Android ListView Adapter notifyDataSetInvalidated () vs notificarDataSetChanged ()
  • Actividad como diálogo en android
  • Cómo ejecutar pruebas en un fragmento de actividades
  • Cómo poner un atributo CardView en un estilo?
  • El problema surge cuando intento insertar en una base de datos a través de mi subclase de ContentProvider dentro del método onFolderContentsResponse; La interfaz de usuario siempre se bloquea mientras se ejecuta el código, lo que me lleva a creer que a pesar de que se llama desde el método doInBackground de un AsyncTask, los insertos siguen funcionando de alguna manera en el subproceso de interfaz de usuario. Esto es lo que parece el código problemático:

     MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() { @Override public void onFolderContentsResponse(final List<FilesystemEntry> contents) { insertContentsIntoDB(contents); } } 

    Y el método insertContentsIntoDB :

     void insertContentsIntoDB(final List<FilesystemEntry> contents) { for (FilesystemEntry entry : contents) { ContentValues values = new ContentValues(); values.put(COLUMN_1, entry.attr1); values.put(COLUMN_2, entry.attr2); // etc. mContentResolver.insert(MyContentProvider.CONTENT_URI, values); } } 

    Donde mContentResolver se ha establecido previamente en el resultado del método getContentResolver ().

    He intentado poner insertContentsIntoDB en su propio hilo, así:

     MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() { @Override public void onFolderContentsResponse(final List<FilesystemEntry> contents) { new Thread(new Runnable() { @Override public void run() { insertContentsIntoDB(contents); } }).run(); } } 

    También he intentado ejecutar cada inserto individual en su propio hilo (el método de inserción en MyContentProvider está sincronizado, por lo que esto no debería causar ningún problema):

     void insertContentsIntoDB(final List<FilesystemEntry> contents) { for (FilesystemEntry entry : contents) { new Thread(new Runnable() { @Override public void run() { ContentValues values = new ContentValues(); values.put(COLUMN_1, entry.attr1); values.put(COLUMN_2, entry.attr2); // etc. mContentResolver.insert(MyContentProvider.CONTENT_URI, values); } }).run(); } } 

    Y sólo por buena medida, también he intentado ambas soluciones con el código correspondiente en el método doInBackground de otro AsyncTask. Finalmente, he definido MyContentProvider explícitamente como viviendo en un proceso separado en mi AndroidManifest.xml:

     <provider android:name=".MyContentProvider" android:process=":remote"/> 

    Funciona bien, pero todavía parece funcionar en el hilo de interfaz de usuario . Ese es el punto donde realmente empecé a arrancarme el pelo por esto, porque eso no tiene ningún sentido para mí. No importa lo que hago, la interfaz de usuario siempre cuelga durante los insertos. ¿Hay alguna manera de conseguir que no?

  • ¿Es posible vincular un TableLayout con un ArrayAdapter?
  • Error interno al utilizar Descubrimiento de servicio de red en Android
  • ¿Cómo puedo crear pestañas para un ViewPager ahora que las pestañas ActionBar están obsoletas (Lollipop)
  • Elige la imagen de la tarjeta sd, cambia el tamaño de la imagen y la guarda de nuevo en la tarjeta sd
  • Detección de red 3G o Wifi
  • Cómo manejar onContextItemSelected en una actividad de múltiples fragmentos?
  • 4 Solutions collect form web for “ContentProvider insert () siempre se ejecuta en el hilo de interfaz de usuario?”

    En lugar de llamar a mContentResolver.insert() , utilice AsyncQueryHandler y su método startInsert() . AsyncQueryHandler está diseñado para facilitar las consultas asincrónicas de ContentResolver .

    Creo que su problema original puede haber sido que está llamando al método run en su nuevo subproceso (que hace que la ejecución continúe en el subproceso actual) en lugar de llamar al método start . Creo que esto es lo que Bright Great estaba tratando de decir en su respuesta. Consulte Diferencia entre ejecutar e iniciar un subproceso . Es un error común.

    Man. Relájate. Y todo parecería mejor. Al principio, Comenzar un hilo es func start no Func ejecutar, si desea iniciar el nuevo hilo no sólo llamar a la función func.

     new Thread(Runnable runnable).start(); 

    Entonces apuesto a usar Handler a veces sería mejor que AsyncTask.

    Puede ejecutar la consulta en el doInBackground(Integer int) sobreescrito de AsynTask y actualizar la interfaz de usuario principal en el onPostExecute(Integer int) .

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.