德尔福从意图提取多个额外的数据崩溃,段错误11
应用程序要处理我使用这个组件意图:德尔福从意图提取多个额外的数据崩溃,段错误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:感谢雷米勒博我已经修正了一些复制/粘贴错误。
段错误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;
这些复制/粘贴错误是你的问题的重要元凶。而不是编辑你的问题来解决它们(从而使整个问题无效),你应该将固定代码作为答案来代替。我已恢复您的编辑。但是,如果您修复了错误并仍然存在问题,那么请使用最新的代码更新问题。顺便说一句,请调试你的代码。您应该能够报告崩溃的确切代码行。 –
无法复制粘贴错误。错误不是复制粘贴。 –