[Android] Análisis del código fuente de Android IntentService

Análisis del código fuente de Android IntentService

1. Introducción

El servicio es uno de los cuatro componentes principales de Android. Se usa para ejecutarse en segundo plano, pero debido a que el servicio aún se está ejecutando en el hilo principal, las operaciones que requieren mucho tiempo no se pueden realizar directamente. Si hay una operación que requiere mucho tiempo, aún debe colocarla en el subproceso secundario, puede iniciar el subproceso manualmente o puede usar una clase muy simple IntentService proporcionada por Android. El código fuente de esta clase aún es muy simple, este artículo analiza su implementación.

二 、 HandlerThread

Antes de analizar IntentService, primero debemos comprender HandlerThread. Al mirar el nombre, sabrá que esta clase es una clase de subproceso relacionada con Handler. La API la describe así:
Clase práctica para iniciar un nuevo subproceso que tiene un looper. El looper se puede usar para crear clases de manejador. Tenga en cuenta que start () aún debe llamar.
es una clase de ayuda para la creación de roscas con objetos Looper. Los objetos Looper se pueden usar para crear clases Handler. Por supuesto, start () todavía se llama para iniciar el hilo.
En el principio de Android Handler en el último artículo, sabemos que cuando un hilo crea un Handler, debe tener un objeto Looper y usar Looper para abrir el bucle de mensajes. En el hilo principal, el sistema ha hecho esto por nosotros. Entonces, si en otros subprocesos secundarios, ¿cómo deberíamos crear Looper? Mire el método run () de HandlerThread:

public void run() {
    
    
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
    
    
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

Looper.prepare () se llama en este método para obtener el objeto Looper para el hilo y guardar el objeto. Luego llame a Looper.loop () para iniciar el bucle de mensajes En este método, hay un bucle infinito que continuamente saca mensajes de la cola de mensajes, por lo que se establece el sistema de mensajes de este hilo. Estos han sido analizados en el artículo anterior.

Tres, IntentService

Descubra HandlerThread, IntentService es muy simple. IntentService usa HandlerThread internamente. IntentService hereda Service y es una clase abstracta. Aquí está su método onCreate ():

public void onCreate() {
    
    
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.

    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

private final class ServiceHandler extends Handler {
    
    
    public ServiceHandler(Looper looper) {
    
    
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
    
    
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1);
    }
}

En este método se crea un objeto HandlerThread y se obtiene su Looper, y luego se crea el Handler con este Looper. El método handleMessage de IntentService transfiere el mensaje recibido a onHandleIntent para su procesamiento. Este método es un método abstracto, y también es un método que necesita ser reescrito cuando usamos IntentService. Después de que se procesa onHandleIntent, IntentService llamará a stopSelf () para detenerse automáticamente. Se llamará a handleMessage en el método Looper.loop () y se ejecutará en HandlerThread, por lo que las operaciones que consumen mucho tiempo se pueden manejar de forma segura.
¿Cómo llegó la noticia? Eche un vistazo al código fuente de onStartCommand ():

public int onStartCommand(Intent intent, int flags, int startId) {
    
    
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
public void onStart(Intent intent, int startId) {
    
    
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

Muy simple, envuelva el parámetro intent en el obj del mensaje y luego envíe el mensaje. El Intent aquí es el Intent en startService (Intent) cuando se inicia el servicio.
Para el servicio, cuando se llama a startService (Intent) varias veces, el método onCreate () solo se llamará una vez, por lo que se realizará un trabajo de inicialización aquí, y onStartCommand se llamará varias veces en consecuencia. Por lo tanto, siempre que los parámetros de Intención sean diferentes, se pueden completar diferentes tareas.

Cuatro, resumen

Como puede verse en el análisis anterior, siempre que comprenda el principio de Handler, IntentService se comprende mejor. Hay varios puntos a tener en cuenta al usar IntentService:
 No se puede interactuar con la IU directamente. Para reflejar los resultados de su ejecución en la interfaz de usuario, los resultados deben devolverse a la actividad.
 La cola de tareas de trabajo se ejecuta secuencialmente. Si una tarea se está ejecutando en IntentService y usted envía una nueva solicitud de tarea en este momento, la nueva tarea esperará hasta que se complete la tarea anterior antes de comenzar a ejecutarse.
La tarea en curso no se puede interrumpir.

Supongo que te gusta

Origin blog.csdn.net/sinat_36955332/article/details/108278905
Recomendado
Clasificación