2017-09-15 23 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