No se puede crear el servicio "Solo se puede crear un Looper por subproceso"

Estoy desarrollando una aplicación para tableta Android 3.1.

Esta aplicación ejecutará un hilo. En sus excepcional Tengo este codigo:

public class UDPSocketBackgroundService extends Service
{

@Override
public void onCreate()
{
    super.onCreate();
    Log.v(TAG, "in onCreate()");

    // xxxxxx
    Looper.prepare();
    mServiceHandler = new Handler() {
        /**
         * 
         */
        public void handleMessage(Message msg)
        {
            DatagramPacket packet = (DatagramPacket) msg.obj;
            //String received = new String(packet.getData(), 0, packet.getLength());

            Message backMsg = Message.obtain();
            backMsg.arg1 = Activity.RESULT_OK;;

            Bundle bundle = new Bundle();
            bundle.putByteArray("CLIENT_DATA", packet.getData());
            bundle.putString("CLIENT_HOST", packet.getAddress().getHostAddress());
            bundle.putString("CLIENT_PORT", new Integer(packet.getPort()).toString());
            backMsg.setData(bundle);

            try
            {
                outMessenger.send(backMsg);
            }
            catch (android.os.RemoteException e1)
            {
                Log.w(getClass().getName(), "Exception sending message", e1);
            }
        }
    };
    Looper.loop();
}

Pero no sé por qué (porque es mi primera vez con los servicios) obtengo una excepción aquí:

Looper.prepare();

ACTUALIZACIÓN

Evento onBind del servicio:

public IBinder onBind(Intent intent)
{
    Bundle extras = intent.getExtras();
    // Get messager from the Activity
    if (extras != null) {
        outMessenger = (Messenger) extras.get("MESSENGER");
    }

    try
    {
        myThread = new UDPServerThread("X", 8888, mServiceHandler);
        myThread.start();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return mMessenger.getBinder();
}

Así empiezo el servicio desde main actividad:

protected void onResume()
{
    super.onResume();

    Intent intent = null;
    intent = new Intent(this, UDPSocketBackgroundService.class);
    // Create a new Messenger for the communication back
    // From the Service to the Activity
    Messenger messenger = new Messenger(handler);
    intent.putExtra("MESSENGER", messenger);

    bindService(intent, conn, Context.BIND_AUTO_CREATE);
}

¿Qué estoy haciendo mal?

preguntado el 04 de julio de 12 a las 08:07

3 Respuestas

1. Servicios no se ejecuta en hilo de fondo, pero en el subproceso de interfaz de usuario dedicada.

2. Se consideró una buena práctica hacer que la interfaz de usuario funcione en el subproceso de la interfaz de usuario y que no funcione en el subproceso de la interfaz de usuario, pero de HoneyComb se convirtió en una regla.

3. Entonces, para su subproceso de fondo, use Thread will Handler o AsyncTask.

4. El trabajo que no es de interfaz de usuario se ejecuta en primer plano mediante Handler, que a su vez requiere un subproceso de interfaz de usuario para llamar a Looper.loop() para obtener los mensajes reales atendidos, Entonces alli esta no es necesario llamar explícitamente Looper.loop() o preparar().

Respondido 04 Jul 12, 08:07

Gracias por tu respuesta. ¿Qué quieres decir con "Thread will Handler"? - Furgonetas Fannel

He actualizado mi pregunta agregando cómo inicio el servicio. No sé si esto es importante para tu respuesta, pero creo que debo decirte. - Furgonetas Fannel

Cuando es necesario que el Servicio deba vincularse con la Actividad, entonces uso public IBinder onBind(Intent intent) , de lo contrario hago todo en onCreate() , onStart o onStartCommand y onDestroy() - Kumar Vivek Mitra

Un servicio se ejecuta en el subproceso de la interfaz de usuario y el subproceso de la interfaz de usuario ya tiene un looper, por lo que recibe ese error.

Si tenía la intención de hacer su trabajo en un subproceso en segundo plano, es posible que deba crear un nuevo subproceso para ese código que desea ejecutar.

Tal vez podrías mirar en Controlador de hilo.

Respondido 04 Jul 12, 08:07

Gracias por tu respuesta. He actualizado mi pregunta agregando cómo inicio el servicio. No sé si esto es importante para tu respuesta, pero creo que debo decirte. - Furgonetas Fannel

En primer lugar, Service no se ejecuta en un subproceso en segundo plano, por lo que debe usar un Thread, un AsyncTask o un IntentService por su trabajo de fondo. Segundo, Service ya tiene un Looper inicializado, hay que quitarlo Looper.prepare() y Looper.loop() de su código.

Respondido 04 Jul 12, 08:07

Gracias por tu respuesta. He actualizado mi pregunta agregando cómo inicio el servicio. No sé si esto es importante para tu respuesta, pero creo que debo decirte. - Furgonetas Fannel

Intenta extender IntentService en lugar de Service y agregue su lógica de fondo a la onHandleIntent(...) método. No tiene que vincular su servicio a su actividad, simplemente puede usar startService(...) con la intención apropiada. Si desea volver a publicar cambios en el subproceso de la interfaz de usuario, puede usar controladores. Pero la mejor práctica sería que usaras AsyncTask en lugar de servicios en este caso. - Adán Monos

Ato mi servicio porque quiero usar messenger para comunicarme de actividad a servicio y reversión. - Furgonetas Fannel

Puede utilizar el AsyncTask's onPreExecute(...), onPostExecute(...) y onProgressUpdate(...) métodos para comunicarse con el subproceso de la interfaz de usuario, creo que debería intentarlo. - Adán Monos

Creo que en ese caso deberías dejar de lado la parte del servicio y crear tu trabajador. Thread y su Handler en su actividad y utilícelos para publicar mensajes en el hilo de la interfaz de usuario. Por lo que puedo decir, solo necesita el servidor UDP mientras su aplicación se está ejecutando, ¿verdad? En ese caso esto sería más fácil. - Adán Monos

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.