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 //: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;

  ///

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

  TMessage = 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,
      procedure(
        const Sender: TObject;
        const M: TMessage )
      begin
        (M as TMessage).Value.StyledSettings
          :=[TStyledSetting.Style];
        (M as TMessage).Value.TextSettings.Font.Family:='微软雅黑';
        (M as TMessage).Value.TextSettings.Font.Size:=20;
        (M as TMessage).Value.TextSettings.FontColor:=TAlphaColorRec.Red;

      end);

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

  AMessage := TMessage.Create(Edit2);
  MessageManager.SendMessage(Sender, AMessage, true);
    //MessageManager.SendMessage(Sender, AMessage, false);
    //:true:相当于false后立即:AMessage.DisposeOf;
    //:每个TMessage在订阅时SubscribeToMessage产生唯一识别1个id
      //:最后TMessage在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://blog.csdn.net/pulledup/article/details/104609245

更多相关文章

  1. Android中的消息机制
  2. (一)Android(安卓)异步消息处理
  3. Unity3D研究院之与Android相互传递消息(十九)
  4. Android(安卓)面试 15 家大厂,这个问题是必问!
  5. Android消息处理惩罚机制(Handler、Looper、MessageQueue与Messag
  6. 图解 Android(安卓)Handler 线程消息机制
  7. Android应用程序线程消息循环
  8. 图解 Android(安卓)Handler 线程消息机制
  9. Android中的网络时间同步

随机推荐

  1. Android如何使用Notification进行通知
  2. android获取手机信息大全
  3. Android(安卓)之 下拉框(Spinner)的使用
  4. Suggestion: add 'tools:replace="androi
  5. android JNI处理图片的例子
  6. Android(安卓)读取Resources和Assets
  7. android获取手机序列号
  8. Android日语输入法Simeji使用示例
  9. Android(安卓)端如何添加自定义表情
  10. Official Note of Android(安卓)(importa