You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi XE10.2开发Android后台服务启动报错及iTask实现求助

问题排查与优化建议

一、初始服务启动问题(访问违规+服务无法启动)

1. 访问违规错误根源

你提到调用Fservice.StartService('TheService')触发访问违规,移除服务jar文件后错误消失但服务无法启动。这大概率是服务jar文件与Delphi XE10.2 Tokyo的Android SDK版本不兼容导致的:

  • Delphi XE10.2对应Android SDK API 25(Android 7.1),如果你的服务jar是针对更高/更低版本编译的,会引发JNI层面的访问错误。
  • 移除jar后,服务缺失了必要的原生依赖,自然无法正常启动。

修复建议:

  • 确保服务jar基于Delphi XE10.2配套的Android SDK编译,或者直接使用Delphi内置的TLocalService组件,避免手动引入第三方jar。
  • 检查AndroidManifest.template.xml中服务的注册是否正确,格式如下:
    <service android:name="com.embarcadero.services.TheService" />
    
  • 改用更可靠的服务启动方式,避免TLocalServiceConnection的潜在问题:
    if switchnotificationenable.IsChecked then
    begin
      var Intent := TJIntent.JavaClass.init(TAndroidHelper.Context, TJTheService.JavaClass);
      TAndroidHelper.Context.startService(Intent);
    end;
    

二、iTask循环实现的问题排查

你改用iTask+Sleep的方式检查时间并发送通知,这段代码存在几个关键问题:

1. 线程安全风险

  • TNotification相关操作(如ScheduleNotification)必须在UI线程执行,但你在后台线程的TTask.Run中直接调用,会引发线程安全问题甚至崩溃。
  • 旧版TQuery组件不适合在后台线程直接操作,容易出现数据集异常或连接泄漏。

2. 循环逻辑的效率与准确性问题

  • Sleep(30000)会阻塞线程,无法及时响应Checking停止信号,建议改用TEvent实现可中断的等待。
  • SameText(FormatDateTime('HH-MM',NotifTime),formatdatetime('HH-MM',today))的时间匹配方式存在临界点误差,比如系统时间刚好卡在30秒间隔边缘时会错过触发,建议直接比较小时和分钟数值。

3. 资源泄漏问题

  • TStringList创建后未调用Free,会导致内存泄漏。
  • 数据库查询循环中反复执行SQL.Clear和Open,未正确关闭数据集,可能引发连接泄漏。

三、优化后的代码示例

针对上述问题,给出调整后的实现:

procedure TDM.AndroidServiceCreate(Sender: TObject);
var
  TheINIFIle: string;
  config: TStringList;
  notiftime: TTime;
  CheckEvent: TEvent;
begin
  TheINIFILE := TPath.Combine(TPath.GetSharedDocumentsPath, 'NotificationParams.ini');
  if not FileExists(TheINIFILE) then Exit;

  config := TStringList.Create;
  try
    config.LoadFromFile(TheINIFILE);
    notiftime := StrToTime(config.Values['TimeNotification']);
    TimerConnection.Database := config.Values['DatabasePath'];
    if not TimerConnection.Connect then Exit;
  finally
    config.Free; // 及时释放资源
  end;

  // 创建可中断事件替代Sleep,支持及时停止循环
  CheckEvent := TEvent.Create(nil, False, False, '');
  TTask.Run(procedure
  var
    Today: TTime;
    Query: TFDQuery; // 使用FireDAC的线程安全数据集
    NeedNotify: Boolean;
  begin
    Query := TFDQuery.Create(nil);
    try
      Query.Connection := TimerConnection;
      Query.SQL.Text := 'select client.entreprise, RDV.date_ntf from client, Rdv where client.num_c = rdv.num_c and rdv.Date_Ntf = date(''now'')';
      
      while Checking do
      begin
        // 等待30秒或收到停止信号
        if CheckEvent.WaitFor(30000) = wrSignaled then Break;

        Today := Time;
        // 精准匹配小时和分钟
        if (HourOf(Today) = HourOf(notiftime)) and (MinuteOf(Today) = MinuteOf(notiftime)) then
        begin
          NeedNotify := False;
          Query.Close;
          Query.Open;
          
          while not Query.Eof do
          begin
            if SameText(Query.FieldByName('date_ntf').AsString, FormatDateTime('yyyy-mm-dd', Now)) then
            begin
              NeedNotify := True;
              Break;
            end;
            Query.Next;
          end;

          if NeedNotify then
          begin
            // 切换到UI线程发送通知
            TThread.Synchronize(nil, procedure
            var
              MyNotification: TNotification;
            begin
              MyNotification := TheNotifications.CreateNotification;
              try
                MyNotification.AlertBody := 'Le RDV avec ' + Query.FieldByName('entreprise').AsString + ' vous attend!';
                TheNotifications.ScheduleNotification(MyNotification);
              finally
                MyNotification.DisposeOf;
              end;
            end);
          end;
        end;
      end;
    finally
      Query.Free;
      CheckEvent.Free;
    end;
  end);
end;

四、额外优化建议

  1. 改用Android原生AlarmManager:系统推荐用AlarmManager实现定时任务,比后台轮询更省电,还能避免系统杀死后台线程。Delphi可通过JNI调用其API。
  2. 调整服务启动模式:你设置的START_REDELIVER_INTENT适合需确保任务完成的场景,若只是定时通知,改用START_STICKY更合适,服务被杀死后会自动重启。
  3. 数据库优化:使用FireDAC组件替代旧版TQuery,它支持线程安全操作和异步查询,稳定性更强。

内容的提问来源于stack exchange,提问作者Amir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:36:16