Android原生消息处理与FMX平台服务消息处理的区别与消息机制

 Android原生消息处理与FMX平台服务消息处理的区别与消息机制

一、通过TApplicationEventMessage获取消息

  { //  原理:  Application events }

  TApplicationEvent = (FinishedLaunching, BecameActive, WillBecomeInactive, EnteredBackground, WillBecomeForeground, WillTerminate, LowMemory, TimeChange, OpenURL);

  TApplicationEventHelper = record helper for TApplicationEvent
  const
    aeFinishedLaunching = TApplicationEvent.FinishedLaunching deprecated 'Use TApplicationEvent.FinishedLaunching';
    aeBecameActive = TApplicationEvent.BecameActive deprecated 'Use TApplicationEvent.BecameActive';
    aeWillBecomeInactive = TApplicationEvent.WillBecomeInactive deprecated 'Use TApplicationEvent.WillBecomeInactive';
    aeEnteredBackground = TApplicationEvent.EnteredBackground deprecated 'Use TApplicationEvent.EnteredBackground';
    aeWillBecomeForeground = TApplicationEvent.WillBecomeForeground deprecated 'Use TApplicationEvent.WillBecomeForeground';
    aeWillTerminate = TApplicationEvent.WillTerminate deprecated 'Use TApplicationEvent.WillTerminate';
    aeLowMemory = TApplicationEvent.LowMemory deprecated 'Use TApplicationEvent.LowMemory';
    aeTimeChange = TApplicationEvent.TimeChange deprecated 'Use TApplicationEvent.TimeChange';
    aeOpenURL = TApplicationEvent.OpenURL deprecated 'Use TApplicationEvent.OpenURL';
  end;

  TApplicationEventData = record
    Event: TApplicationEvent;
    Context: TObject //:适用于任何对象的订阅后的消息处理
    constructor Create(const AEvent: TApplicationEvent; AContext: TObject);
  end;
  TApplicationEventMessage = class (System.Messaging.TMessage<TApplicationEventData> //:delphi原生调用
  public  //:具有独立于FMX的通用的消息机制,即VCL也适用
     constructor Create(const AData: TApplicationEventData);
  end;

  TApplicationEventHandler = function (AAppEvent: TApplicationEvent; AContext: TObject): Boolean of object;
 

  //用下面的方式订阅消息,你可以处理和发布任意对象的任何消息:
  //FEventManagerID:=
  TMessageManager.DefaultManager.SubscribeToMessage(
    const AMessageClass: TClass; const AListener: TMessageListener
  ): Integer;

  //FEventManagerID:=
  TMessageManager.DefaultManager.SubscribeToMessage(
    const AMessageClass: TClass; const AListenerMethod: TMessageListenerMethod
  ): Integer;

  TMessageListener = reference to procedure(const Sender: TObject; const M: TMessage);
  TMessageListenerMethod = procedure (const Sender: TObject; const M: TMessage) of object;

  /// <summary>Base class for all messages</summary>
  TMessageBase = class abstract;
  TMessage = TMessageBase;
  {$NODEFINE TMessage} // Avoid ambiguity with 'Winapi.Messages.TMessage'

  TMessage<T> = class (TMessage)
  protected
    FValue: T;
  public
    constructor Create(const AValue: T);
    destructor Destroy; override;
    property Value: T read FValue;
  end;
比如:订阅一个TEdit的字体属性对象的消息:

  MsgSubscriptionId2 := //System.Messaging.TMessageListener:
    MessageManager.SubscribeToMessage(
      TMessage<TEdit>,
      procedure(
        const Sender: TObject;
        const M: TMessage )
      begin
        (M as TMessage<TEdit>).Value.StyledSettings
          :=[TStyledSetting.Style];
        (M as TMessage<TEdit>).Value.TextSettings.Font.Family:='微软雅黑';
        (M as TMessage<TEdit>).Value.TextSettings.Font.Size:=20;
        (M as TMessage<TEdit>).Value.TextSettings.FontColor:=TAlphaColorRec.Red;

      end);

//返回用消息管理器订阅的监听方法或监听事件来发消息:
  //:MessageManager.SendMessage:
//:OnCreate等地方:写了订阅代码:
var
  MessageManager: TMessageManager;
  AMessage: TMessage;
begin
  MessageManager := TMessageManager.DefaultManager;

  AMessage := TMessage<TEdit>.Create(Edit2);
  MessageManager.SendMessage(Sender, AMessage, true);
    //MessageManager.SendMessage(Sender, AMessage, false);
    //:true:相当于false后立即:AMessage.DisposeOf;
    //:每个TMessage<T>在订阅时SubscribeToMessage产生唯一识别1个id
      //:最后TMessage<T>在Create并SendMessage用完之后必须释放DisposeOf,否则内存泄漏

结果:

二、IFMXApplicationEventService通过FMX平台服务获取消息

       在学习《delphi调用及封装Android原生控件》的直播课程过程中,有朋友粘了这段代码通过平台服务TPlatformServices,我们也经常用到类似接口调用的方式,但其实还是与1、TApplicationEventMessage的实现是有区别的。

var SvcEvents:IFMXApplicationEventService;

// 后台事件
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(SvcEvents)) then
    SvcEvents.SetApplicationEventHandler(HandleAppEvent);
//HandleAppEvent
function TFormMain.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
  // APP进入到后台,10秒之内切回到前台,不做二次验证。
  // APP进入到后台,超过10秒切回到前台,再次进行指纹验证。
  // 记录进入后台的时间data 时入后台时检查时间差 10以内不需要验证
  //

  case AAppEvent of
    TApplicationEvent.FinishedLaunching:
      ; // ShowMessage('FinishedLaunching');
    TApplicationEvent.BecameActive: // 主窗体重新激活也会触发 很频繁一般建议少用
      // begin
      // ShowMessage('BecameActive'); // 第一次运行app触发,从后台切换过来也触发

      ;
    TApplicationEvent.WillBecomeInactive:    // ShowMessage('WillBecomeInactive')
      ;
    TApplicationEvent.EnteredBackground:
      begin
      
      end;

      // ShowMessage('EnteredBackground'); //切换到后台
      TApplicationEvent.WillBecomeForeground:      // ShowMessage('WillBecomeForeground'); // 从后台切换到前台
      if Gsettingjson.TimeLimit <> tlNone then
      begin
     

      end;

    TApplicationEvent.WillTerminate:
      ; // ShowMessage('WillTerminate');
    TApplicationEvent.LowMemory:
      ;
    TApplicationEvent.TimeChange:
      ;
    TApplicationEvent.OpenURL:
      ;
  end;
  Result := True;
end;

//  原理:
  IFMXApplicationEventService = interface(IInterface)
    ['{F3AAF11A-1678-4CC6-A5BF-721A24A676FD}']
    procedure SetApplicationEventHandler(AEventHandler: TApplicationEventHandler);
  end;  //:1、FMX接口调用,而且只能处理应用程序级别的事件消息TApplicationEventHandler,2、而非任意对象TObject级别的事件消息,比如一个TEdit的任意属性对象的消息

  //:3、FMX所特有的,VCL不适用,4、是用接口去写实现,来达到目的的,5、另VCL下调用FMX控件等代码时,也不适用的

三、参见:

https://mp.csdn.net/console/editor/html/104609245

发布了80 篇原创文章 · 获赞 9 · 访问量 9859

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/105065671
今日推荐