2017-09-15 20 views
0

应用程序要处理我使用这个组件意图:德尔福从意图提取多个额外的数据崩溃,段错误11

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

我的应用程序有2个不同的意图接收器。作为浮子的阵列的第一个目的输出只是1个标记(DATA),该第二意图具有3个标签(SUM_DATA,MIN_DATA和MAX_DATA)是浮动的每个阵列。

这是我如何注册他们:

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; 

有时它不工作,因为它应该。它确实点击开始按钮后立即崩溃有时段错误11的应用程序(在我的情况将Button3,见上面的代码)。有时候,我得到异常: 访问冲突在地址C84E2FC6,访问地址00000018和应用程序将继续正常运行。或者它可以正常运行。

我敢肯定,我失去了一些东西 - 我是新来的Delphi Android上的编码。谢谢!

UPD1:感谢雷米勒博我已经修正了一些复制/粘贴错误。

+0

这些复制/粘贴错误是你的问题的重要元凶。而不是编辑你的问题来解决它们(从而使整个问题无效),你应该将固定代码作为答案来代替。我已恢复您的编辑。但是,如果您修复了错误并仍然存在问题,那么请使用最新的代码更新问题。顺便说一句,请调试你的代码。您应该能够报告崩溃的确切代码行。 –

+1

无法复制粘贴错误。错误不是复制粘贴。 –

回答

2

段错误11是Android的相当于Windows中的访问冲突。

:好吧,Linux的等价物,但Android是建立在Linux之上的。邻近地址0

访问冲突通常意味着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_MAX变量分配给您的ACCEL_SUM变量,而不是:

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! 

在一个侧面说明,你的UI操作是里面的if块为MAXDataStr数组检索。那是你真正想要的吗?如果是这样,UI时,才会更新,如果该特定领域存在(让你的其他变量没用)。

或者,你想每次接收Intent更新了UI,无论它提供的领域?如果是这样(我怀疑这是你真正想要的),你需要移动UI代码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; 

话虽这么说,我会建议您简化程序,以避免重复代码,修复上面提到的错误。尝试更多的东西是这样的:

procedure TMainScreen.AccelBroadcastReceiverReceive(Context: JContext; Intent: JIntent); 
var 
    csv_buffer: string; 

    function GetIntentFloatValue(Key: JString): Single; 
    var 
    Arr: TJavaArray<Single>; 
    begin 
    Arr := Intent.getFloatArrayExtra(Key); 
    if (Arr <> nil) and (Arr.Length > 0) then 
    begin 
     Result := Arr[0]; 
     if (Result <= no_data) then Result := -1; 
    end else 
     Result := -1; 
    end; 

begin 
    try 
    ACCEL_SUM := GetIntentFloatValue(SUMDataStr); 
    ACCEL_MIN := GetIntentFloatValue(MINDataStr); 
    ACCEL_MAX := GetIntentFloatValue(MAXDataStr); 

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

    csv_buffer := Format('%f,%f,%f,%f', [HR, ACCEL_SUM, ACCEL_MAX, ACCEL_MIN]); 
    if Remcue.IsChecked then csv_buffer := csv_buffer + Format(',%f,%d', [HRV, STAGE]); 
    Remcue.Text := 'REM Alarm (beta) REM detected:' + IntToStr(Remcue.Tag); 
    Label1.Text := FloatToStr(ACCEL_SUM); 
    Memo1.Lines.Add(csv_buffer); 
    AccelTimer.Tag := 0; 
    except 
    on E : Exception do 
     Memo1.Lines.Add('Accel Exception = ' + E.Message); 
    end; 
end; 
+0

哦,我的坏。就在这里复制代码之前,我已经使用了一个DataStr和一个Arr,就像在其他答案中一样,但后来决定将其转换 - 这就是为什么这么多的复制/粘贴错误。现在修好了,但仍然崩溃。我会在一秒钟内更新代码。 – MonZon

+0

谢谢!这比我实施这个要好得多)尽管如此,仍然崩溃。我会尝试调试,但不知何故,在新的Delphi甚至断点不起作用,我将不得不调查更多。 – MonZon

+0

这次崩溃是我的TMemo造成的。现在我使用TStringList来存储数据,一切都很好。谢谢你的帮助!你的代码很棒! – MonZon