uso studio programacion peticiones móviles hilos funciona desarrollo curso como asynctask asincronos asincronas aplicaciones android multithreading android-asynctask ui-thread
publicado un código de apoyo

studio - manual de programacion android pdf



¿Es posible usar AsyncTask en una clase de servicio? (5)

Todo está en el título.

En las documentaciones oficiales se indica que los Note that services, like other application objects, run in the main thread of their hosting process y AsyncTask solo funciona si se ejecuta en UIThread.

Entonces, ¿es posible usar AsyncTask en una clase de servicio?

Estoy tratando de hacerlo pero siempre obtengo el mismo error

05-01 18:09:25.487: ERROR/JavaBinder(270): java.lang.ExceptionInInitializerError

...

05-01 18:09:25.487: ERROR/JavaBinder(270): Caused by: java.lang.RuntimeException: Can''t create handler inside thread that has not called Looper.prepare()

¿Estoy haciendo algo mal o es esto simplemente imposible?

Aquí está el código de mi clase de servicio

package com.eip.core; import android.app.Service; import android.content.Intent; import android.os.AsyncTask; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class NetworkService extends Service { private final INetwork.Stub mBinder = new INetwork.Stub() { @Override public int doConnect(String addr, int port) throws RemoteException { new ConnectTask().execute("test42"); return 0; } }; @Override public IBinder onBind(Intent arg0) { return mBinder; } private class ConnectTask extends AsyncTask<String, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); Log.i("OnPreExecute()", ""); } @Override protected Void doInBackground(String... arg0) { Log.i("doInBackground()", ""); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); Log.i("OnPostExecute()", ""); } } }


¿Es posible usar AsyncTask en una clase de servicio?

Sí. Ver Reto Meier (2010) Desarrollo profesional de aplicaciones para Android 2 , Wrox. Meier ha publicado un código de apoyo (vea / Capítulo 9 Terremoto 4 / src / com / paad / terremoto / EarthquakeService.java):

public class EarthquakeService extends Service { ... private EarthquakeLookupTask lastLookup = null; ... private class EarthquakeLookupTask extends AsyncTask<Void, Quake, Void> { ... } @Override public int onStartCommand(Intent intent, int flags, int startId) { ... refreshEarthquakes(); return Service.START_NOT_STICKY; }; private void refreshEarthquakes() { ... lastLookup = new EarthquakeLookupTask(); lastLookup.execute((Void[])null); ... } }

Por otro lado, no puedo encontrar ninguna evidencia que respalde su afirmación de que " AsyncTask solo funciona si se ejecuta en UIThread " (aunque esto violaría las reglas de enhebrado ).


Aunque es posible utilizar AsyncTask en una clase de Service , esto infringe las reglas de subprocesamiento , en particular, AsyncTask debe AsyncTask una instancia e invocarse en el subproceso de la interfaz de usuario. (Consulte https://.com/a/25172977/3664487 para obtener más información).


Creo que encontré por qué no funciona en mi caso.

Aquí estoy usando esto:

private final INetwork.Stub mBinder = new INetwork.Stub() { @Override public int doConnect(String addr, int port) throws RemoteException { new ConnectTask().execute("test42"); return 0; } };

Estoy usando esto para hacer lo que se conoce como IPC, comunicación entre procesos , así que supongo que mi servicio y mi actividad están en dos procesos diferentes, AsyncTask debe ejecutarse en el hilo de la interfaz de usuario principal de acuerdo con el documento de Android, entonces ¿por qué estaba tratando? hacer me parece simplemente imposible de acuerdo con esos hechos.

Si estoy equivocado, por favor alguien puede corregirme.


Tal vez el problema no sea AsyncTask sino algo más. Por ejemplo, ¿estás seguro de que tu método onBind funciona correctamente? Por favor intente esto:

@Override public IBinder onBind(Intent arg0) { return null; }

También podrías intentar eso

public class NetworkService extends Service{ @Override public void onStart(Intent intent, int startId) { new ConnectTask().execute("test42"); } }


También asegúrese de revisar IntentService. Si esa clase es suficiente para sus necesidades, se ocupará de muchos detalles pequeños necesarios para que ese patrón funcione correctamente.