2010-11-14 23 views
26

Estoy desarrollando una aplicación de Android y estoy haciendo un trabajo pesado (trayendo datos de una página web en línea y analizándolo para almacenarlos en la base de datos) en un servicio. Actualmente, lleva unos 20 minutos y para este momento mi IU está atascada. Estaba pensando en usar un hilo en servicio para que mi UI no se atasque pero da error. Estoy utilizando el siguiente código:¿Cómo iniciar un nuevo hilo en un servicio?

Thread thread = new Thread() 
{ 
     @Override 
     public void run() { 
      try { 
       while(true) { 
        sleep(1000); 
        Toast.makeText(getBaseContext(), "Running Thread...", Toast.LENGTH_LONG).show(); 
       } 
      } catch (InterruptedException e) { 
      Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show(); 
      } 
     } 
    }; 

thread.start(); 

Este código simple está dando error de tiempo de ejecución. Incluso si saco el ciclo while, todavía no está funcionando. Por favor, ¿alguien puede decirme qué error estoy cometiendo? Aparentemente, copié este código directamente de un libro electrónico. Se supone que debe funcionar, pero no es así.

+0

¿Qué es el "error de tiempo de ejecución"? – theomega

+0

Si bloquea el hilo de UI por más de 5 segundos en Android, obtendrá un error. Entonces, definitivamente necesitas un hilo nuevo para terminar tu tarea en segundo plano. – Zelimir

+0

La aplicación simplemente falla. ¿Es esta la manera correcta de crear un hilo? –

Respuesta

31

Ejemplo de nueva creación hilo tomado de muestras Android (android-8 \ SampleSyncAdapter \ src \ com \ ejemplo \ androide \ samplesync \ client \ NetworkUtilities.java):

public static Thread performOnBackgroundThread(final Runnable runnable) { 
    final Thread t = new Thread() { 
     @Override 
     public void run() { 
      try { 
       runnable.run(); 
      } finally { 

      } 
     } 
    }; 
    t.start(); 
    return t; 
} 

runnable es el Ejecutable que contiene sus operaciones de red.

+0

Esto parece ser una función que significa que necesita ser llamado. debo llamar es como: performOnBackgroundThread (nuevo Runnable() {....? en onCreate() de servicio? –

+0

No necesita usarlo como una función. Puede usarlo como lo hizo originalmente. Lo importante es que creas nuevo Runnable y colocas el código que se comunica con el servidor. Por lo tanto, no puedes simplemente poner Runnable() nuevo como un argumento de la función performOnBackgroundThread(), necesitas definir Runnable nuevo como entidad (función) separada. – Zelimir

+0

El original el código también inicia un hilo. Esta respuesta no está haciendo nada diferente.Pero al menos sabemos que oficialmente está permitido comenzar un hilo :) – qris

37

mandamiento Android: tu no puedes interactuar con los objetos de interfaz de usuario de sus propios hilos

envolver su visualización pan tostado en runOnUIThread(new Runnable() { });

+7

¿cuántos otros mandamientos conoce usted? :) – ajacian81

+21

No los conté, pero cada uno de ellos viene de golpear la cabeza en la mesa –

+1

esto debería ser aceptado y marcado como la respuesta correcta – likejiujitsu

2

Es posible definir sus puestos de trabajo en un objeto ejecutable, utilice un objeto hilo para ejecutarlo y inicie este hilo en la función onStartCommand() de su servicio. Aquí es mis notas:

En su clase de servicio:

  1. definir su bucle principal en un objeto Runnable
  2. crear Thread objeto con el objeto ejecutable como parámetro

En su servicio de la clase de onStartCommand método():

  1. call th leer función de arranque del objeto()

mi código:

private Runnable busyLoop = new Runnable() { 
    public void run() { 
     int count = 1; 
     while(true) { 
      count ++; 
      try { 
       Thread.sleep(100); 
      } catch (Exception ex) { 
       ; 
      } 
      ConvertService.running.sendNotification("busyLoop" + count);      
     } 
    } 
}; 

public int onStartCommand(Intent intent, int flags, int startId) { 
    sendNotification("onStartCommand"); 
    if (! t.isAlive()) { 
     t.start(); 
    } 
    return START_STICKY; 
} 
+2

Plx, pon un ejemplo completo, no lo entendí ... – DarckBlezzer

9

Puede utilizar HandlerThread y publicar en él, aquí es un ejemplo de servicio que tiene uno.

public class NetworkService extends Service { 

    private HandlerThread mHandlerThread; 
    private Handler mHandler; 
    private final IBinder mBinder = new MyLocalBinder(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     mHandlerThread = new HandlerThread("LocalServiceThread"); 
     mHandlerThread.start(); 

     mHandler = new Handler(mHandlerThread.getLooper()); 
    } 

    public void postRunnable(Runnable runnable) { 
     mHandler.post(runnable); 
    } 

    public class MyLocalBinder extends Binder { 
     public NetworkService getService() { 
      return NetworkService.this; 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 
} 
Cuestiones relacionadas