Monday, April 7, 2014

Que es un servicio android?

Es una app que corre de forma automática, sin intervención del usuario. Estos pueden ser servidos web, servicios de comunicaciones, antivirus por mencionar algunos.
En android un servicio no es independiente, corren en el mismo proceso que la aplicación que los consume.
Las actividades, las intenciones y los proveedores de contenido  son de corta duración y pueden ser detenidos en cualquier momento.

Los servicios están pensados para seguir corriendo, y si es necesario, de manera independiente de cualquier actividad. 

El ejemplo más  simple para aterrizar este concepto es el del reproductor de música, que es un servicio que puede mantenerse corriendo mientras mandamos un SMS o lanzamos alguna otra app.

 Adicionalmente, un componente puede vincularse a un servicio (Bound Service) para interactuar con él, llegando a realizar comunicación entre procesos (IPC). Todas estas tareas pueden estar en segundo plano.

Un servicio puede tomar 2 formas no excluyentes: 
● Iniciado: El servicio es llamando por el método  startService(), lo que resulta en una llamada al método onStartCommand() del servicio. Este puede correr indefinidamente en segundo plano, incluso si el componente que lo inicio es destruido. Usualmente  un servicio iniciado realiza una sola operación y no regresa un resultado, por ejemplo, para descargar o cargar un  archivo en la red. Una vez realizada la operación, el servicio mismo debería detenerse, llamando al método  stopSelf(). Puede darse el caso de que haya muchas llamadas al método startService(), lo que ejecutaría muchas veces el método onStartCommand() del servicio, pero no importa cuantas veces se inicie un servicio, será detenido llamando al método stopSelf() dentro del servicio o stopService() desde fuera . 

● Vinculado (bound): servicio llamado por el método  bindService(), lo que resulta en una llamada al método onBind() del servicio. El servicio de vinculación (Bound Service) es el servidor en la interfaz cliente-servidor, permite a los componentes (los cliente, como las Activities) vincularse a el servicio, solicitar peticiones, recibir respuestas e incluso hacerlo a través de IPC. El cliente se  comunica con el servicio a través de la interfaz IBinder que es devuelta por el método onBind() del servicio. Un servicio de vinculación se ejecuta solo mientras algún componente de la aplicación está vinculado a él. Muchos  componentes pueden vincularse al servicio, sin embargo el método onBind(), solo se ejecutará la primera vez, el resto solamente devolverá el objeto IBinder. Cuando todos se desvinculen (llamando al método unbindService()) , el servicio es destruido (a menos que también se haya iniciado por el método startService()). 

Empezando con el servicio

  • Empieza el proyecto con el wizard.


import android.app.Activity;
import android.os.Bundle;
public class inicio extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

  • Cambiemos el extends de  Activiy ha  Service
    • . Además, le meteremos los métodos requeridos por el interfaz (onBind) y otros métodos necesarios (OnDestroy, ServiceStart y ServiceStop):


  • import android.app.Service;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.IBinder;
    public class EjemploServicio extends Service
    {
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate();
            // Iniciamos el servicio
            this.iniciaServicio();
        }
        public void onDestroy()
        {
            super.onDestroy();
            // Detenemos el servicio
            this.finalizaServicio();
        }
        public IBinder onBind(Intent intent)
        {
            // No usado de momento
            return null;
        }
        public void iniciaServicio()
        {
        }
        public void finalizaServicio()
        {
        }
    }


  •  AndroidManifest.xml por lo tanto:
    • <?xml version="1.0" encoding="utf-8"?>
    • <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="seroton.test.servicio" android:versionCode="1" android:versionName="1.0">
    • <application android:label="@string/app_name">
    • <service android:name="nombrecontruta.dse.ccbas.uaa"/>
    • </application>
    • </manifest>

  • Haciendo algo en el servicio
 
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
 
public class EjemploServicio extends Service
{
    public static Activity ACTIVIDAD;
    private Timer timer = null;
 
    public static void establecerActividadPrincipal(Activity actividad)
    {
        EjemploServicio.ACTIVIDAD=actividad;
    }
 
    public void onCreate()
    {
        super.onCreate();
 
        // Iniciamos el servicio
        this.iniciarServicio();
 
        Log.i(getClass().getSimpleName(), "Servicio iniciado");
    }
 
    public void onDestroy()
    {
        super.onDestroy();
 
        // Detenemos el servicio
        this.finalizarServicio();
 
        Log.i(getClass().getSimpleName(), "Servicio detenido");
    }
 
    public IBinder onBind(Intent intent)
    {
        // No usado de momento, sólo se usa si se va a utilizar IPC
        // (Inter-Process Communication) para comunicarse entre procesos
        return null;
    }
 
    public void iniciarServicio()
    {
        try
        {
            Log.i(getClass().getSimpleName(), "Iniciando servicio...");
 
            // Creamos el timer
            this.timer=new Timer();
 
            // Configuramos lo que tiene que hacer
            this.timer.scheduleAtFixedRate ( new TimerTask() { public void run() { ejecutarTarea(); } }, 0, 1000 // Cada segundo );
 
            Log.i(getClass().getSimpleName(), "Temporizador iniciado");
        }
        catch(Exception e)
        {
            Log.i(getClass().getSimpleName(), e.getMessage());
        }
    }
 
    public void finalizarServicio()
    {
        try
        {
            Log.i(getClass().getSimpleName(), "Finalizando servicio...");
 
            // Detenemos el timer
            this.timer.cancel();
 
            Log.i(getClass().getSimpleName(), "Temporizador detenido");
        }
        catch(Exception e)
        {
            Log.i(getClass().getSimpleName(), e.getMessage());
        }
    }
 
    private void ejecutarTarea()
    {
        Log.i(getClass().getSimpleName(), "Ejecutando tarea...");
 
        // Reflejamos la tarea en la actividad principal
        TestServicio.ACTIVIDAD.runOnUiThread ( new Runnable()
        {
            public void run()
            {
                TextView ejecuciones=(TextView)TestServicio.ACTIVIDAD.findViewById(R.id.TextView01);
                ejecuciones.append(".");
            }
        } );
    }
}

  • Lanzando el servicio

 
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
 
public class TestServicioLanzador extends Activity
{
    ProgressBar barraProgreso=null;
    TextView ejecuciones=null;
 
    public void onCreate(Bundle savedInstanceState)
    {
        // Iniciamos y establecemos el layout super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        // Asociamos los controles
        this.barraProgreso=(ProgressBar)findViewById(R.id.ProgressBar01);
        this.ejecuciones=(TextView)findViewById(R.id.TextView01);
 
        // Establecemos la actividad principal para el servicio
        TestServicio.ACTIVIDAD=this;
 
        // Iniciamos el servicio
        try
        {
            Log.i(getClass().getSimpleName(), "Iniciando servicio desde la actividad...");
 
            // Cogemos el intent el servicio
            Intent servicio = new Intent(this, TestServicio.class);
 
            // Lo ejecutamos
            if(startService(servicio)==null)
            {
                this.notificar("No se ha podido iniciar el servicio");
            }
            else
            {
                this.notificar("Servicio iniciado correctamente");
            }
        }
        catch(Exception e)
        {
            this.notificar(e.getMessage());
        }
    }
 
    public void onDestroy()
    {
        super.onDestroy();
 
        try
        {
            // Finalizamos el servicio
            Log.i(getClass().getSimpleName(), "Finalizando el servicio desde la actividad...");
 
            // Cogemos el intent el servicio
            Intent servicio = new Intent(this, TestServicio.class);
 
            // Lo ejecutamos
            if(stopService(servicio))
            {
                this.notificar("Servicio finalizado correctamente");
            }
            else
            {
                this.notificar("No se ha podido finalizar el servicio");
            }
 
            // Salimos
            this.finalize();
        }
        catch (Throwable e)
        {
            this.notificar(e.getMessage());
        }
    }
 
    private void notificar(String cadena)
    {
        // Notificamos con un toast
        Context contexto = getApplicationContext();
        CharSequence texto = cadena;
        int duracion = Toast.LENGTH_SHORT;
        Toast toast = Toast.makeText(contexto, texto, duracion);
        toast.show();
    }
}

Seguidamente definiremos el layout (en main.xml):
</pre>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Servicio iniciado. Puedes salir de ésta aplicación con las teclas Back o Home." />
</LinearLayout>
<pre>

Y luego definiremos la actividad en el manifiesto
</pre>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Pulsa Back o Home para finalizar el servicio." android:padding="10px"/> <ProgressBar android:id="@+id/ProgressBar01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center">
</ProgressBar> <TextView android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Ejecuciones: " android:padding="10px"/>
</LinearLayout>
<pre>

No comments:

Post a Comment