ABAP中如何取消对于某一事件(EVENT)的监听?

1. 背景

在ABAP中,我们可以通过SET HANDLER ... FOR ...的方式来监听某一个事件(例如ALV中的button click事件),当事件触发后,相应的hander程序会被触发。

而在有些场景下,我们可能会遇到这样的需求,也即在某些条件下,需要取消对于某事件的监听,这应该如何实现呢?

2. 解决方案

这个场景的解决方案,需要使用到ACTIVATION关键字。其完整的语法如下:

SET HANDLER handler1 handler2 … FOR { oref |{ALL INSTANCES} }
[ACTIVATION act].

可以在ACTIVATION关键字后,指定单字符的文本类字段,来控制handler的行为。

  • 如果act的值为'X'(默认值),则注册事件处理程序。

  • 如果act的值为空' ',则取消对事件处理程序的注册。

注意:

  1. 不能通过大规模取消注册(SET HANDLER … FOR ALL INSTANCES ACTIVATION abap_false)来取消单一注册(SET HANDLER … FOR oref ACTIVATION abap_true )。
  2. 反之,在大规模登记之后( SET HANDLER … FOR ALL INSTANCES ACTIVATION abap_true),个别的对象也不能被排除在登记之外(SET HANDLER … FOR oref ACTIVATION abap_false )。

另外,只要没有使用ACTIVATION abap_false的方式取消事件处理程序或删除注册的引发实例oref,ABAP的垃圾收集器(Garbage Collector)就不会删除相关对象,因为它仍然被运行时框架使用。因此,从性能的角度考量,在事件响应后,应考虑是否需要取消对于事件的继续监听。

3. 示例

下面的示例代码展示了如何取消事件监听。

首先,为类LCL_TRIGGER中事件EVENT的所有实例,都注册事件处理程序,因而,所有用NEW创建的实例的事件都会被lo_hander处理,直到注册停止。

REPORT zevent_test.

CLASS lcl_trigger DEFINITION.
  PUBLIC SECTION.
    EVENTS event
      EXPORTING VALUE(msg) TYPE string DEFAULT `nop`.
    METHODS raise_event
      IMPORTING iv_msg TYPE string.
ENDCLASS.

CLASS lcl_trigger IMPLEMENTATION.
  METHOD raise_event.
    RAISE EVENT event EXPORTING msg = iv_msg.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_hander DEFINITION.
  PUBLIC SECTION.
    METHODS handle_event FOR EVENT event OF lcl_trigger
      IMPORTING msg.
ENDCLASS.

CLASS lcl_hander IMPLEMENTATION.
  METHOD handle_event.
    write /  msg .
  ENDMETHOD.
ENDCLASS.


START-OF-SELECTION.
  " 1) register event hander to monitor EVENT
  FINAL(lo_handler) = NEW lcl_hander( ).
  SET HANDLER lo_handler->handle_event FOR ALL INSTANCES ACTIVATION abap_true.

  " 2) simulate event is triggered
  NEW lcl_trigger( )->raise_event( `Ping 1` ).
  NEW lcl_trigger( )->raise_event( `Ping 2` ).
  NEW lcl_trigger( )->raise_event( `Ping 3` ).

  " 3) de-register the monitor of EVENT
  SET HANDLER lo_handler->handle_event FOR ALL INSTANCES ACTIVATION abap_false.

  " 4) see what will happen after de-resigering
  NEW lcl_trigger( )->raise_event( `Ping 4` ).
  NEW lcl_trigger( )->raise_event( `Ping 5` ).
  NEW lcl_trigger( )->raise_event( `Ping 6` ).

程序的运行结果如下:

在这里插入图片描述
在关闭事件监听后,新触发的事假将不会再被响应。

4. 小结

本文简介了ABAP中事件EVENT的用法,并介绍了如何取消对于某一事件的监听。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十年铸器

给作者赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值