Una introducción al Servicio en Android

Introducción a esta sección

Ok, hemos estudiado y estudiado la Actividad en Android en las primeras tres secciones, ¡creo que te beneficiarás mucho! Al comienzo de esta sección, sigamos aprendiendo el segundo componente en Android: Service (servicio), bueno, sin más preámbulos, ¡comencemos esta sección!


1. Conceptos relacionados de hilos

Antes de comenzar a aprender Servicio, comprendamos algunos conceptos de subprocesos.

1) Conceptos relacionados:

  • Programa : Un conjunto de instrucciones escritas en un lenguaje (un conjunto de códigos estáticos ) para realizar una tarea específica
  • Proceso : un programa en ejecución , una unidad independiente de programación del sistema y asignación de recursos , ¡el sistema operativo asignará una sección de espacio de memoria para cada proceso! ¡El programa se ejecuta dinámicamente de forma secuencial, a través del proceso completo de carga de código, ejecución y finalización de la ejecución!
  • Subproceso : una unidad de ejecución más pequeña que un proceso. Cada proceso puede tener múltiples subprocesos. Los subprocesos deben colocarse en un  proceso para ejecutarse. Los subprocesos son administrados por programas y los procesos son programados por el sistema.
  • Comprensión de subprocesos múltiples : ejecute varias instrucciones en paralelo y asigne segmentos de tiempo de CPU a cada subproceso de acuerdo con el algoritmo de programación. De hecho, se ejecuta en tiempo compartido , pero el tiempo de conmutación es muy corto y el usuario se siente " simultáneamente"!

2) El ciclo de vida de un hilo:

3) Tres formas de crear hilos:

  1. Heredar la clase Thread
  2. Implementar la interfaz Runnable
  3. Si implementa la interfaz Callable  : si usa el hilo creado por 2, puede iniciarlo directamente así:
    hilo nuevo(mihilo).start();
    Cuando más a menudo nos gusta usar clases anónimas, es decir, la siguiente forma de escribir:
    nuevo hilo (nuevo Runnable () { 
         public void run (); 
             }). start ();

2. La diferencia entre hilo de servicio y hilo

De hecho, no hay mucha relación entre los dos, ¡pero muchos amigos a menudo los confunden! ¡El subproceso es un subproceso, la unidad más pequeña de ejecución del programa y la unidad básica de asignación de CPU! El servicio es un componente proporcionado por Android que le permite permanecer en segundo plano durante mucho tiempo. ¡El uso más común es para realizar operaciones de sondeo! O quiere hacer algo en segundo plano, como descargar actualizaciones en segundo plano. ¡Recuerda no confundir estos dos conceptos!


3. Diagrama del ciclo de vida del servicio


4. Análisis del ciclo de vida

Ok, del ciclo de vida en la figura anterior, podemos saber que hay dos formas de usar el Servicio en Android:

1) StartService () para iniciar el Servicio
2) BindService () para iniciar el Servicio
PD: Hay otro tipo, es decir, después de iniciar el Servicio, ¡vincule el Servicio!


1) Explicación detallada de los métodos relacionados:

  • onCreate() : Este método se vuelve a llamar inmediatamente después de que se crea el Servicio por primera vez. ¡Este método solo se llamará una vez en todo el ciclo de vida!
  • onDestory() : Este método se devolverá cuando se cierre el Servicio, ¡y este método solo se devolverá una vez!
  • onStartCommand(intent,flag,startId) : la versión anterior es onStart(intent,startId), a la que se devolverá la llamada cuando el cliente llame al método startService(Intent), y se puede llamar al método StartService varias veces, pero no a un nuevo servicio. se creará el objeto, y es para continuar reutilizando el objeto de servicio generado anteriormente, ¡pero continuará llamando al método onStartCommand()!
  • IBinder onOnbind(intent) : Este método es un método que todos los servicios deben implementar. Este método devolverá un objeto IBinder, y la aplicación se comunica con el componente Servicio a través de este objeto.
  • onUnbind(intent) : ¡Se devolverá la llamada a este método cuando todos los clientes vinculados al Servicio estén desconectados!

2) StartService inicia el servicio

Se creará una instancia de Servicio en el primer inicio, y los métodos onCreate() y onStartCommand() se llamarán a su vez. En este momento, el Servicio entrará en estado de ejecución. Si se vuelve a llamar a StartService para iniciar el Servicio, no se creará ningún objeto de servicio nuevo, y el sistema reutilizará directamente el objeto de servicio creado anterior, ¡llame a su método onStartCommand ()!
②Pero dicho Servicio no tiene una conexión necesaria con la persona que llama, es decir, cuando la persona que llama finaliza su propio ciclo de vida, pero mientras no se llame a stopService, ¡el Servicio continuará ejecutándose! comenzó
, solo necesita llamar a StopService una vez para detener el servicio


3) BindService inicia el servicio

①Al usar bindService para vincular un Servicio por primera vez, el sistema creará una instancia de Servicio y llamará a sus métodos onCreate() y onBind(), y luego la persona que llama puede interactuar con el Servicio a través de IBinder. una nueva instancia de Servicio, y no llamará al método onBind(), ¡solo pasará directamente el objeto IBinder a otros clientes agregados más tarde!②Si
desvinculamos el servicio, solo necesitamos llamar a unbindService(), los métodos onUnbind y onDestory ser llamado en este momento! Este es el caso de un cliente. Si varios clientes están vinculados al mismo Servicio, la situación es la siguiente. Cuando un cliente completa la interacción con el servicio, llama al método unbindService() para desvincular. Cuando todos los clientes estén desvinculados del servicio, el sistema destruirá el servicio. (A menos que el servicio también se inicie con el método startService())
③Además , a diferencia de la situación anterior, el Servicio en el modo bindService está relacionado con la persona que llama, que puede entenderse como "saltamontes en una cuerda", y deben morir juntos Después de bindService, una vez que la persona que llama destruye, el servicio terminará inmediatamente
El análisis del bindService del contexto llamado cuando se llama al servicio a través de BindService  bindService (Intent Service, ServiceConnection conn, int flags)
service : especifique el Service conn para ser comenzó a través de la intención
: objeto ServiceConnection, el usuario supervisa la conexión entre el visitante y el Servicio, y se devuelve la llamada al método onServiceConnected(ComponentName, IBinder) en el objeto si la conexión es exitosa; si el host donde se encuentra el Servicio finaliza debido a terminación u otros motivos, el Servicio y el visitante están desconectados. Llame al método onServiceDisconnected , desconéctese activamente a través del método unBindService()  y no llamará al método anterior.
Indicadores : Especifica si crear automáticamente un Servicio al vincular ( si el Servicio aún no ha sido creado), el parámetro puede ser 0 (no creado automáticamente), BIND_AUTO_CREATE (creación automática)


4) Después de que StartService inicia el Servicio, bindService se vincula

Si el Servicio ha sido iniciado por un cliente a través de StartService(), y luego otros clientes llaman a bindService() para enlazar con el Servicio, llaman a unbindService() para desvincular, y finalmente llaman a bindService() para enlazar al Servicio, El ciclo de vida activado en este momento es el siguiente:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
PD: La premisa es: ¡el método onUnbind() devuelve verdadero! ser parte Los lectores tienen dudas. Después de llamar a unbindService, ¿no debería el Servicio llamar al método onDisory()? De hecho, esto se debe a que el Servicio es iniciado por nuestro StartService, por lo que si llama al método onUnbind() para desvincular, el Servicio no terminará
La conclusión extraída:  usamos bindService para vincular un Servicio iniciado, ¡preste atención al Servicio iniciado! El sistema simplemente pasa el objeto IBinder interno del Servicio a la Actividad, y no vincula el ciclo de vida del Servicio con la Actividad Vinculación, por lo que al llamar al método unBindService ( ) para cancelar la vinculación, ¡el Servicio no se destruirá!


5. Verificación del ciclo de vida

A continuación, escribimos código para verificar el ciclo de vida:

1) Verificar la secuencia de llamada de StartService para iniciar el Servicio

Primero, personalizamos un Servicio, reescribimos los métodos relevantes y el usuario imprime la verificación en el logcat:

TestService1.java

public class TestService1 extends Service {   
    private final String TAG = "TestService1";     
    //métodos que deben implementarse   
    @Override   
    public IBinder onBind(Intent intent) {   
        Log.i(TAG, "¡se llama al método onBind!");   
        return null;   
    }   
  
    //Cuando se crea el Servicio, llama a   
    @Override   
    public void onCreate() {   
        Log.i(TAG, "¡Se llama al método onCreate!");   
        super.onCreate();   
    }   
      
    //Cuando se inicia el Servicio, llama   
    @Override   
    public int onStartCommand (intento de intención, banderas int, int startId) {   
        Log.i(TAG, "¡se llama al método onStartCommand!");    
        return super.onStartCommand(intent, flags,  ID de inicio);
    }   
      
    //Devolución de llamada antes de que se cierre el servicio  
    @Override   
    public void onDestroy() {   
        Log.i(TAG, "¡Se llama al método onDestory!");   
        super.onDestroy();   
    }   
}

AndroidManifest.xml completa el registro del servicio

<!-- Configure el componente Servicio y configure una acción al mismo tiempo -->   
<service android:name=".TestService1">   
            <intent-filter>   
                <action android:name="com.jay.example.service. TEST_SERVICE1"/>   
            </intent-filter>   
</service>  

Luego hay un archivo de diseño simple, dos botones y, finalmente, la escritura de MainActivity, que llama a startService ( ) y stopService ( ) respectivamente en el evento de clic del botón.

MainActivity de clase pública extiende la actividad {   
  
    inicio de botón privado;   
    parada de botón privado;   
      
    @Override   
    protected void onCreate(Bundle SavedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.activity_main);   
          
        start = (Button) findViewById(R .id .btnstart);   
        stop = (Button) findViewById(R.id.btnstop);   
        //Crear el Intent para iniciar el Servicio, y la propiedad Intent   
        final Intent intent = new Intent();   
        intent.setAction("com.jay. ejemplo.servicio .TEST_SERVICE1");   
        //Establecer eventos de clic para dos botones, iniciar y detener el servicio respectivamente   
        start.setOnClickListener(new OnClickListener() {              
            @Override    
            public void onClick(View v) {  
                startService(intención);                 
            }   
        });  
          
        stop.setOnClickListener(nuevo OnClickListener() {            
            @Override   
            public void onClick(View v) {   
                stopService(intent);   
                  
            }   
        });  
    }   
}

Ejecute la captura de pantalla:

Haga clic para iniciar el servicio:

No hay nada que hacer cuando esté lleno, ordene algunos más:

Finalmente haga clic en detener el servicio:

Análisis de resultados:

A partir de los resultados de ejecución anteriores, podemos verificar el contenido explicado en nuestro diagrama de ciclo de vida: Descubrimos que no se ha llamado al método onBind(), y al hacer clic para iniciar el Servicio varias veces, ¡solo se llamará al método onStartCommand repetidamente! muchas veces iniciamos el Servicio, ¡Un stopService detendrá el Servicio!


2) Verifique el orden en que BindService inicia el Servicio:

Antes de comenzar a escribir código, primero debemos comprender algunas cosas: primero, el método de contexto bindService que se proporciona debajo de la primera imagen general:

  • Objeto ServiceConnection: Supervise la conexión entre el visitante y el Servicio. Si la conexión es exitosa, vuelva a llamar a onServiceConnected(). Si el Servicio se desconecta del visitante debido a una terminación anormal u otras razones, se devolverá la llamada al método onServiceDisconnected. Llamada ¡unBindService() no llamará a este método!
  • ¡Hay un objeto IBinder en el método onServiceConnected, que puede realizar la comunicación con el servicio enlazado! Cuando desarrollamos la clase de servicio, necesitamos implementar el método IBinder onBind() de forma predeterminada, y el objeto IBinder devuelto por este método será pasado al objeto ServiceConnection En el parámetro onServiceConnected, ¡podemos comunicarnos con el Servicio a través de este IBinder aquí!

Resumen:
Paso 1: Herede Binder en el Servicio personalizado e implemente su propio objeto IBinder
Paso 2: Devuelva su propio objeto IBinder a través del método onBind()
Paso 3: Defina un objeto ServiceConnection en la clase que vincula el Servicio, reescriba Dos métodos, onServiceConnected y onDisconnected! ¡Entonces lea directamente los parámetros pasados ​​por IBinder!

Bueno, el siguiente paso es escribir la verificación del código. ¡Aquí definimos un Servicio para el tiempo y luego demostramos el uso de BindService y el proceso de llamada al método! El código es relativamente simple, ¡así que no lo explicaré!

TestService2.java:

public class TestService2 extends Service {   
    private final String TAG = "TestService2";   
    private int count;   
    private boolean quit;   
      
    //Definir el objeto devuelto por el método onBinder   
    private MyBinder binder = new MyBinder();   
    public class MyBinder extends Binder   
    {   
        public int getCount ()   
        {   
            return count;   
        }   
    }   
      
    //Un método que debe implementarse, que se vuelve a llamar cuando se cambia el enlace a Service   
    @Override   
    public IBinder onBind(Intent intent) {   
        Log.i(TAG, "onBind method is call !");   
        return binder ;   
    }   //Callback 
    @Override   
  
    cuando se crea el Servicio  
    public void onCreate() {   
    @Override  
        super.onCreate();   
        Log.i(TAG, "¡Se llama al método onCreate!");   
        //Crea un hilo para modificar dinámicamente el valor de count   
        new Thread()   
        {   
            public void run()    
            {   
                while(!quit)   
                {   
                    try   
                    {   
                        Thread.sleep(1000);   
                    }catch(InterruptedException e){e.printStackTrace();}   
                    count++;   
                }   
            };   
        }.start();   
          
    }   
      
    //Devolución de llamada cuando el servicio está desconectado  
    public boolean onUnbind(Intent Intent) {   
        Log.i(TAG, "¡Se llama al método onUnbind!");   
        return true;   
    }   
      
    //Devolución de llamada antes de que se cierre el servicio   
    @Override   
    public void onDestroy() {   
        super.onDestroy();   
        this. quit = true;   
        Log.i(TAG, "¡Se llama al método onDestroyed!");   
    }   
      
    @Override   
    public void onRebind(Intent intent) {   
        Log.i(TAG, "¡Se llama al método onRebind!");   
        super.onRebind(intent );   
    }   
}

Registre el componente Servicio en AndroidManifest.xml:

<service android:name=".TestService2" android:exported="false">   
        <intent-filter>   
            <action android:name="com.jay.example.service.TEST_SERVICE2"/>   
        </intent-filter>   
</ servicio>  

MainActivity.java:

public class MainActivity extends Activity {   
  
    private Button btnbind;   
    private Button btncancel;   
    private Button btnstatus;   
      
    //Mantenga el objeto IBinder del servicio iniciado y defina un objeto ServiceConnection   
    TestService2.MyBinder binder;   
    private ServiceConnection conn = new ServiceConnection() {   
          
        // Se vuelve a llamar a este método cuando se desconectan la Actividad y el Servicio   
        @Override   
        public void onServiceDisconnected(ComponentName name) {   
            System.out.println("------Service DisConnected-------");   
        }   
          
        //Actividad y Este método se devuelve cuando la conexión del servicio es exitosa   
        @Override   
        public void onServiceConnected(ComponentName name, IBinder service) {  
            System.out.println("------Servicio conectado-------");  
        intent.setAction("com.jay.example.service.TEST_SERVICE2");  
            carpeta = (TestService2.MyBinder) servicio;  
        }   
    };  
      
    @Override   
    protected void onCreate(Paquete de estado de instancia guardado) {   
        super.onCreate(estado de instancia guardado);  
        setContentView(R.diseño.actividad_principal);  
        btnbind = (Botón) findViewById(R.id.btnbind);  
        btncancel = (Botón) findViewById(R.id.btncancel);  
        btnstatus = (Botón) findViewById(R.id.btnstatus);  
        intención final intención = nueva intención ();  
        btnbind.setOnClickListener(nuevo OnClickListener() {             
            @Override   
            public void onClick(Ver v) {   
                //servicio de 绑定   
                bindService(intent, conn, Service.BIND_AUTO_CREATE);                   
            }   
        });  
          
        btncancel.setOnClickListener(new OnClickListener() {   
            @Override   
            public void onClick(View v) {   
                //解除service绑定  
                unbindService(conn);                   
            }   
        });  
          
        btnstatus.setOnClickListener(nuevo OnClickListener() {   
            @Override   
            public void onClick(Ver v) {   
                Toast.makeText(getApplicationContext(), "Service的count的值为:"   
                        + binder.getCount(), Toast.LENGTH_SHORT).show();   
            }   
        });  
    }   
}  

Ejecute la captura de pantalla:

Haga clic para bloquear el servicio:

Continuar haciendo clic en el candado: nada cambia

Obtener el estado del Servicio actual:

Desatar:

Si cerramos la actividad directamente después de vincular nuevamente, se informará un error y luego se llamará automáticamente a los métodos onUnbind y onDestory.

 。。。 

A partir de los resultados anteriores, se verifica en el diagrama del ciclo de vida:

Use BindService para vincular el servicio, llame a los métodos onCreate() y onBind() a su vez, podemos devolver un objeto IBinder personalizado en el método onBind(); luego llame al método onServiceConnected() de ServiceConnection, que puede obtener el objeto IBinder, por lo que en cuanto a realizar operaciones relacionadas; cuando el Servicio no está vinculado, llamará automáticamente a los métodos onUnbind y onDestroyed. Por supuesto, en el caso de vincular varios clientes, debe desvincular todos los vínculos antes de llamar al método onDestoryed para su destrucción.

Supongo que te gusta

Origin blog.csdn.net/leyang0910/article/details/131291558
Recomendado
Clasificación