3

我正在尝试将新的 OS X 10.9 (Mavericks) 方法beginActivityWithOptions方法添加到 FireMonkey (Delphi XE2) 中的NSProcessInfo接口 ( TNSProcessInfo)。

该功能似乎有效。它返回一个对象,但是,它不会为应用程序禁用 App Nap。我正在使用 Activity Monitor 的 Energy 选项卡来监控 App Nap 状态。

我已将以下代码添加到Macapi.Foundation.pas

const
  NSActivityBackground = 255;
  NSActivityIdleSystemSleepDisabled = 1048576;
  NSActivityUserInitiated = NSActivityIdleSystemSleepDisabled or 16777215;
  NSActivityLatencyCritical = 1095216660480;

type
  NSActivityOptions = UInt64;

  NSProcessInfo = interface(NSObject)
    ['{B96935F6-3809-4A49-AD4F-CBBAB0F2C961}']
    ...
    // Added following
    function beginActivityWithOptions(options: NSActivityOptions; reason: NSString): NSObject; cdecl;
    ...
  end;

我这样称呼它:

var
  obj: NSObject;
  reason: NSString;
  options: NSActivityOptions;
begin
  reason := NSSTR('...');
  options := NSActivityUserInitiated or NSActivityLatencyCritical;
  obj := TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo).beginActivityWithOptions(options, reason);
end;

我已经尝试了选项标志的各种组合,它并没有禁用 App Nap。有任何想法吗?你觉得我的实现有什么问题吗?

4

2 回答 2

3

谢谢!我一直在处理与 App Nap 相关的相同问题,但使用 NSProcessInfo disableAutomaticTermination 和 enableAutomaticTermination 没有成功。我尝试了您使用 beginActivityWithOptions 的想法,现在效果很好。我相信您唯一的错误是您需要创建一个 NSProcessInfo 实例,该实例分配给类中的字段。你这样做的方式,当 TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo) 超出范围时,你对活动所做的修改就会丢失。

在我的测试中,我创建了一个表单

TForm46 = class(TForm)
  procedure FormCreate(Sender: TObject);
private
  ProcessInfo: NSProcessInfo;
public
end;

然后在 FormCreate

procedure TForm46.FormCreate(Sender: TObject);
begin
  ProcessInfo := TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo);
  ProcessInfo.beginActivityWithOptions(NSActivityUserInitiated or NSActivityLatencyCritical, NSSTR('Good Reason'));
end;

然后我将它部署到我的 mac 并运行它,并使用 Activity Monitor 对其进行监控。它似乎可以按预期工作,应用程序一次保持在 App Nap No 状态数小时。

顺便说一句,整个 App Nap 似乎都被通过 PAServer 运行应用程序所愚弄了。我必须部署然后在 Mac 上本地运行。

于 2013-10-30T21:17:25.180 回答
0

从你的帖子开始,我做了这个单元以避免修改“Macapi.Foundation.pas”我创建“Macapi.Foundation.Ext.pas”

单元 Macapi.Foundation.ext;

interface
uses  Macapi.ObjCRuntime, Macapi.ObjectiveC, Macapi.CocoaTypes,
      Macapi.CoreFoundation, Macapi.CoreServices,Macapi.Foundation;

type

  NSProcessInfoExt = interface(NSProcessInfo)
    ['{1458E7B6-B64E-430E-8DE4-A19C680C17D3}']
    // add process begin
    // Added following
    function beginActivityWithOptions(options: NSActivityOptions; reason: NSString): NSObject; cdecl;
  end;
  TNSProcessInfoExt = class(TOCGenericImport<NSProcessInfoClass, NSProcessInfoExt>)
  public
    class procedure disableAppNap(Areason : String = 'Your reason to disable appNap');
  end;


var
  ProcessInfo: NSProcessInfoExt;

implementation

{ TNSProcessInfoExt }

class procedure TNSProcessInfoExt.disableAppNap(Areason: String = 'Your reason to disable appNap');
const
  NSActivityBackground = 255;
  NSActivityIdleSystemSleepDisabled = 1048576;
  NSActivityUserInitiated = NSActivityIdleSystemSleepDisabled or 16777215;
  NSActivityLatencyCritical = 1095216660480;

type
  NSActivityOptions = UInt64;
var
  obj: NSObject;
  reason: NSString;
  options: NSActivityOptions;
begin
 reason := NSSTR(Areason);
 options := NSActivityUserInitiated or NSActivityLatencyCritical;
 obj := TNSProcessInfoExt.Wrap(TNSProcessInfo.OCClass.processInfo).beginActivityWithOptions(options, reason);



  ProcessInfo := TNSProcessInfoExt.Wrap(TNSProcessInfo.OCClass.processInfo);
  ProcessInfo.beginActivityWithOptions(NSActivityUserInitiated or NSActivityLatencyCritical,reason);


end;

end.

因此,当您需要禁用 appNap 时,您只需将“Macapi.Foundation.Ext.pas”添加到表单的使用中并调用该过程来禁用应用程序小睡,例如:

  {$IFDEF MACOS}
    TNSProcessInfoExt.disableAppNap('Maintain web server active');
  {$ENDIF}

我写了一篇关于这个论点的文章:https ://synaptica.info/2022/02/17/delphi-disable-appnap-on-macosx-application/

于 2022-02-17T12:02:57.853 回答