Android - EventBus

统计时间 2023.4.30
最后版本更新时间 2021.12.8
version 3.3.1
star 24.3k

1. Los escenarios de uso de EventBus
2. ¿Cuál es la diferencia entre EventBus y BroadcastReceiver?
3. ¿Qué patrones de diseño se utilizan en EventBus?
4. ¿Cuáles son las precauciones para EventBus?
5. ¿Cuál es el principio de implementación de EventBus?
6. ¿Cómo se implementa el sticky event de EventBus?

Introducción a EventBus

EventBus es un bus de eventos para Android y Java.
Simplifica la comunicación entre Actividad, Fragmento, Hilo, Servicio, etc.
● Desacoplar emisores y receptores de eventos (según las características de los observadores)
● Evitar dependencias complejas y propensas a errores y problemas de ciclo de vida
Puede establecer la prioridad de suscriptores y subprocesos de entrega
Menos código, mejor calidad.

Escenas a utilizar

1. Notificación de mensaje

Por ejemplo, si le gusta un dato en la página de detalles, debe actualizarse cuando se sincroniza con la página de lista.

2. Al transferir datos grandes entre componentes, Intent tendrá un límite de 1 MB

Los datos grandes no se pueden pasar a través de Intent, estarán limitados por el tamaño de Binder. En este momento, se puede usar EventBus en su lugar

3. Comunicación entre componentes

uso básico

1. Agregue dependencias a build.gradle

implementation 'org.greenrobot:eventbus:3.3.1'

2. Definir eventos

class MessageEvent

3. Prepara a los suscriptores

override fun onStart() {
    
    
    super.onStart()
    EventBus.getDefault().register(this)
    Log.d("yhblock", "EventBus register")
}

override fun onStop() {
    
    
    super.onStop()
    EventBus.getDefault().unregister(this)
    Log.d("yhblock", "EventBus unregister")
}

@Subscribe
fun onMessageEvent(event: MessageEvent) {
    
    
    Log.d("yhblock", "onMessageEvent: " + Thread.currentThread().name)
}

4. Publicar eventos

EventBus.getDefault().post(MessageEvent())

Especifica el hilo del suscriptor.

En el método del suscriptor, es posible que se deban realizar algunas operaciones en el subproceso principal. En este momento, el subproceso de ejecución del método se puede especificar mediante threadMode en @Subscribe.

@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEvent) {
    
    
    Log.d("yhblock", "onMessageEvent: " + Thread.currentThread().name)
}

ThreadMode.POSTING (predeterminado)
se ejecutará en el mismo hilo que el publicador, sin cambiar de hilo y sin la sobrecarga de cambiar de hilo.
Bueno para tareas simples que se sabe que se completan en un corto período de tiempo sin requerir el subproceso principal
ThreadMode.MAIN
Cambia al subproceso principal si el editor no está en el subproceso principal. Si el editor está en el hilo principal, se maneja igual que ThreadMode.POSTING.
Es adecuado para tareas que deben realizarse en el subproceso principal, como actualizar la interfaz de usuario del subproceso principal. Se llamará a los suscriptores
de ThreadMode.MAIN_ORDERED en el hilo principal de Android.
Los eventos siempre se ponen en cola para su posterior entrega a los suscriptores, por lo que las llamadas para publicar regresarán de inmediato. Esto proporciona un orden más estricto y coherente para el procesamiento de eventos (de ahí el nombre MAIN_ORDERED). Por ejemplo, si publica otro evento dentro de un controlador de eventos en el modo de subproceso principal, el segundo controlador de eventos terminará antes que el primero (porque se llama sincrónicamente, compárelo con una llamada de método). Para MAIN_ORDERED, el primer controlador de eventos se completará y luego se llamará al segundo controlador de eventos en un momento posterior (siempre que el subproceso principal tenga capacidad).
Los controladores de eventos que usan este patrón deben regresar rápidamente para evitar bloquear el hilo principal.
ThreadMode.BACKGROUND
Si el editor está en el subproceso principal, cambiará al subproceso de fondo para su procesamiento. Si el editor está en un subproceso en segundo plano, la tarea se procesará directamente en el subproceso actual.
Adecuado para tareas a corto plazo ejecutadas en subprocesos en segundo plano
ThreadMode: ASYNC
abrirá subprocesos por separado
Adecuado para tareas que consumen mucho tiempo realizadas en segundo plano, como solicitudes de red

evento pegajoso

A veces, el evento se enviará antes de la suscripción. En este momento, si se suscribe nuevamente, no recibirá los datos anteriores. Para asegurarse de que los datos se puedan recibir, puede configurarlos como fijos.

1. Recibir eventos fijos

@Subscribe(sticky = true)
fun onMessageStickyEvent(event: MessageStickyEvent){
    
    
    Log.d("yhblock", "onMessageStickyEvent: " + Thread.currentThread().name)
}

2. Enviar eventos fijos

EventBus.getDefault().postSticky(MessageStickyEvent())

Los eventos fijos se envían cuando el EventBus está registrado con la clase actual

EventBus pre register
onMessageStickyEvent: main
EventBus register

Precauciones

1. Use EventBus con precaución

A menos que haya escenarios especiales, como una gran transmisión de datos y sincronización de actualizaciones de estado, es mejor no usar EventBus en otros casos y usar esto como la última solución. Debido a que el observador de EventBus es demasiado flexible, ha causado muchos problemas para la mantenibilidad del código. Aumentó la complejidad del código, especialmente cuando se hace cargo de los proyectos de otros desarrolladores, es demasiado doloroso

2. Los eventos fijos deben cancelarse a tiempo

3. Evite el registro y la cancelación repetidos

//注册
if(!EventBus.getDefault().isRegistered(this)) {
    
    
    EventBus.getDefault().register(this)
}
//取消注册
if (EventBus.getDefault().isRegistered(this)) {
    
    
    EventBus.getDefault().unregister(this)
}

Recomendaciones

1. Asociar el ciclo de vida de EventBus a través de Lifecycle para reducir el código en Actividad

class LifecycleEventBus : DefaultLifecycleObserver {
    
    

    override fun onStart(owner: LifecycleOwner) {
    
    
        if (!EventBus.getDefault().isRegistered(this)) {
    
    
            EventBus.getDefault().register(owner)
        }
        super.onStart(owner)
    }

    override fun onStop(owner: LifecycleOwner) {
    
    
        super.onStop(owner)
        if (EventBus.getDefault().isRegistered(this)) {
    
    
            EventBus.getDefault().unregister(owner)
        }
    }
}

class MainActivity : AppCompatActivity() {
    
    

    private val lifecycleEventBus = LifecycleEventBus()

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(lifecycleEventBus)
    }
}

2. Use un evento unificado para reducir la cantidad de clases de eventos

data class CommonEvent(val eventId: Int)

material

Documentación de EventBus

Guess you like

Origin blog.csdn.net/Android_yh/article/details/130451079