Delphi从intent中提取多个额外数据会使用segfault 11破坏应用程序

时间:2017-09-15 16:56:44

标签: delphi android-intent

使用此组件处理意图:

https://github.com/barisatalay/delphi-android-broadcast-receiver-component

我的应用有2个不同的意图接收器。第一个intent只输出1个标签(DATA)作为float数组,第二个intent有3个标签(SUM_DATA,MIN_DATA和MAX_DATA),每个标签都是一个float数组。

以下是我注册的方式:

procedure TMainScreen.FormCreate(Sender: TObject);
begin
  HRBroadcastReceiver.RegisterReceive;
  AccelBroadcastReceiver.RegisterReceive;
end;

procedure TMainScreen.Button3Click(Sender: TObject);     //start button
begin
  HRDataStr := StringToJString('DATA');
  SUMDataStr := StringToJString('SUM_DATA');
  MINDataStr := StringToJString('MIN_DATA');
  MAXDataStr := StringToJString('MAX_DATA');
  HRBroadcastReceiver.Add(HR_DATA);
  AccelBroadcastReceiver.Add(ACCEL_DATA);
end;

这是我的解析代码:

procedure TMainScreen.AccelBroadcastReceiverReceive(Context: JContext;
  Intent: JIntent);
var
  MINArr, MAXArr, SUMArr: TJavaArray<Single>;
  csv_buffer: string;
begin
  {$I-}
  try
    if Intent.hasExtra(SUMDataStr) = true then
    begin
      SUMArr := Intent.getFloatArrayExtra(SUMDataStr);
      if (SUMArr <> nil) and (SUMArr.Length > 0) then
      begin
        ACCEL_SUM := SUMArr[0];
        if (ACCEL_SUM <= no_data) then ACCEL_SUM := -1;
      end else
        ACCEL_SUM := -1;
    end;

    if Intent.hasExtra(SUMDataStr) = true then
    begin
      MINArr := Intent.getFloatArrayExtra(MINDataStr);
      if (MINArr <> nil) and (MINArr.Length > 0) then
      begin
        ACCEL_MIN := MINArr[0];
        if (ACCEL_MIN <= no_data) then ACCEL_MIN := -1;
      end else
        ACCEL_MIN := -1;
    end;

    if Intent.hasExtra(SUMDataStr) = true then
    begin
      MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
      if (MAXArr <> nil) and (MAXArr.Length > 0) then
      begin
        ACCEL_MAX := MAXArr[0];
        if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1;
      end else
        ACCEL_SUM := -1;

      if ( (ACCEL_SUM = -1) and (ACCEL_MAX = -1) and (ACCEL_MIN = -1) ) then
      begin
        HR := -1;
        Label2.Text := FloatToStr(HR);
      end;

      csv_buffer := FloatToStr(HR) + ',' + FloatToStr(ACCEL_SUM) + ',' + FloatToStr(ACCEL_MAX) + ',' + FloatToStr(ACCEL_MIN);
      if (Remcue.IsChecked = true) then csv_buffer := csv_buffer + ',' + FloatToStr(HRV) + ',' + IntToStr(STAGE);
      Remcue.Text := 'REM Alarm (beta)   REM detected:' + IntToStr(remcue.Tag);
      Label1.Text := FloatToStr(ACCEL_SUM);
      Memo1.Lines.Add(csv_buffer);
      AccelTimer.Tag := 0;
    end;
  {$I+}
  except
    on E : Exception do
      Memo1.Lines.Add('Accel Exception = ' + E.Message);
  end;
end;

有时它不能正常工作。在点击开始按钮后,它有时会使用segfault 11崩溃应用程序(在我的情况下,按钮3,请参阅上面的代码)。有时我得到例外: 地址为C84E2FC6的访问冲突,访问地址00000018,应用程序继续正常运行。或者它可以正常运行。

我确定我错过了一些东西 - 我是熟悉Android编码的delphi新手。谢谢!

UPD1:感谢Remy Lebeau,我修复了一些复制/粘贴错误。

1 个答案:

答案 0 :(得分:2)

Segfault 11是Android的 1 相当于Windows中的访问冲突。

1 :嗯,Linux是等价的,但Android是建立在Linux之上的。

地址0附近的访问冲突通常意味着正在访问$.ajax({ dataType: "json", url: url, data: data, success: success }); 指针。我在你的代码中看到了几个可能导致错误的拼写错误。

例如:

nil

您正在查询是否存在if Intent.hasExtra(SUMDataStr) = true then // <-- should be MINDataStr instead! begin MINArr := Intent.getFloatArrayExtra(MINDataStr); 字段,但之后您正在检索SUMDataStr字段的数组。如果请求的字段不存在,MINDataStr将返回getFloatArrayExtra()

nil数组字段相同:

MAXDataStr

此外,如果if Intent.hasExtra(SUMDataStr) = true then // <-- should be MAXDataStr instead! begin MAXArr := Intent.getFloatArrayExtra(MAXDataStr); 为空或空,则表示您将MAXArr值分配给-1变量而不是ACCEL_SUM变量:

ACCEL_MAX

另外,您的UI处理位于if Intent.hasExtra(SUMDataStr) = true then begin MAXArr := Intent.getFloatArrayExtra(MAXDataStr); if (MAXArr <> nil) and (MAXArr.Length > 0) then begin ACCEL_MAX := MAXArr[0]; if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1; end else ACCEL_SUM := -1; // <-- should be ACCEL_MAX instead! 数据块检索的if块内。那是你真正想要的吗?如果是这样,只有在存在特定字段时才会更新UI(使其他变量无用)。

或者,您是否希望在收到MAXDataStr时更新UI,而不管它提供的字段是什么?如果是这样(我怀疑这是你真正想要的),你需要将UI代码移到Intent块之外:

if

话虽如此,我建议简化您的程序以避免重复代码,并修复上述错误。尝试更像这样的东西:

procedure TMainScreen.AccelBroadcastReceiverReceive(Context: JContext;
  Intent: JIntent);
var
  MINArr, MAXArr, SUMArr: TJavaArray<Single>;
  csv_buffer: string;
begin
  {$I-}
  try
    if Intent.hasExtra(SUMDataStr) = true then
    begin
      SUMArr := Intent.getFloatArrayExtra(SUMDataStr);
      if (SUMArr <> nil) and (SUMArr.Length > 0) then
      begin
        ACCEL_SUM := SUMArr[0];
        if (ACCEL_SUM <= no_data) then ACCEL_SUM := -1;
      end else
        ACCEL_SUM := -1;
    end;

    if Intent.hasExtra(MINDataStr) = true then
    begin
      MINArr := Intent.getFloatArrayExtra(MINDataStr);
      if (MINArr <> nil) and (MINArr.Length > 0) then
      begin
        ACCEL_MIN := MINArr[0];
        if (ACCEL_MIN <= no_data) then ACCEL_MIN := -1;
      end else
        ACCEL_MIN := -1;
    end;

    if Intent.hasExtra(MAXDataStr) = true then
    begin
      MAXArr := Intent.getFloatArrayExtra(MAXDataStr);
      if (MAXArr <> nil) and (MAXArr.Length > 0) then
      begin
        ACCEL_MAX := MAXArr[0];
        if (ACCEL_MAX <= no_data) then ACCEL_MAX := -1;
      end else
        ACCEL_MAX := -1;
    end; // <-- 'end' moved here!

    if ( (ACCEL_SUM = -1) and (ACCEL_MAX = -1) and (ACCEL_MIN = -1) ) then
    begin
      HR := -1;
      Label2.Text := FloatToStr(HR);
    end;

    csv_buffer := FloatToStr(HR) + ',' + FloatToStr(ACCEL_SUM) + ',' + FloatToStr(ACCEL_MAX) + ',' + FloatToStr(ACCEL_MIN);
    if (Remcue.IsChecked = true) then csv_buffer := csv_buffer + ',' + FloatToStr(HRV) + ',' + IntToStr(STAGE);
    Remcue.Text := 'REM Alarm (beta)   REM detected:' + IntToStr(remcue.Tag);
    Label1.Text := FloatToStr(ACCEL_SUM);
    Memo1.Lines.Add(csv_buffer);
    AccelTimer.Tag := 0;

    // <-- 'end' removed from here!
  {$I+}
  except
    on E : Exception do
      Memo1.Lines.Add('Accel Exception = ' + E.Message);
  end;
end;
相关问题