Delphi Android RESTRequest:频道无法恢复,将被处理

时间:2016-06-30 18:57:04

标签: android rest delphi crash firemonkey

多次运行RESTRequest.Execute后没有任何错误,我的Android应用程序随机崩溃。

虽然我正在使用Firemonkey进行开发,但我只能通过在Android Studio的DDMS logcat中进行检查来解决错误。

  

535-614 /? E / InputDispatcher:channel'221d0340 com.mycompany.myappname / com.embarcadero.firemonkey.FMXNativeActivity(server)'〜频道无法恢复,将被处置!

我发现它通常表示应用程序中存在内存泄漏,但是我对如何防止它发生无能为力。

  • Delphi的调试显示完全没有崩溃。

这就是我在主窗体上调用RESTRequest的方法:

procedure TFormMain.ExecuteReadingThread(Sender: TObject);
begin

    aReadingThread := TThread.CreateAnonymousThread(
        procedure()
        begin

            try
                json_data_response_object := DM_KVA.GetDeviceData(communication_token, genset_id);
            except
                on E: Exception do
                begin
                    // Ignore
                end;
            end;

            TThread.Queue(aReadingThread,
            procedure()
            begin

            // Send UI Adjustments with a Thread-safe method

            end);


        end);

    // Default Threading Settings
    aReadingThread.FreeOnTerminate := true;
    aReadingThread.OnTerminate     := TerminateRead;
    aReadingThread.Start;

end;

procedure TFormMain.TerminateRead(Sender: TObject);
begin

        // Make Reading Thread take it's place
        ExecuteReadingThread(Sender);

end;

这就是它在DataModule

上执行的方式
function TDM_KVA.GetDeviceData(ID_Token: string; ID_Device: string): TJSONObject;
var

    JSObj: TJSONObject;

begin

    // Set default RESTRequest parameters
    RESTRequest_KVA.Resource       := 'api/v1/TServerMethods1';
    RESTRequest_KVA.Method         := REST.Types.TRESTRequestMethod.rmGET;
    RESTRequest_KVA.ResourceSuffix := Format('DeviceData/%s', [ID_Device]);

    try
        // Execute command
        RESTRequest_KVA.Execute;

    except
        on E: EIdHTTPProtocolException do
        begin
            // Ignore
        end;
        on E: TRESTResponse.EJSONValueError do
        begin
            // Ignore
        end;
        on E: EIdUnknownProtocol do
        begin
            // Ignore
        end;

    end;

    // Verify response
    case (RESTResponse_KVA.StatusCode) of

        200:
        begin

            // Successful readz
            JSObj  := (RESTRequest_KVA.Response.JSONValue as TJSONObject);
            Result := JSObj;

        end;

    end;

end;

如何避免这些随机内存泄漏导致Android应用程序崩溃?

1 个答案:

答案 0 :(得分:2)

在编写代码时,json_data_response_object的范围似乎比ExecuteReadingThread宽。

在ARC内存模型下,当对象超出范围时,会自动处理该对象。但是这里调用ExecuteReadingThread之间并没有超出范围。相反,指向对象的指针会不断被覆盖,直到没有内存(大量泄漏)为止。

  

如何避免这些随机内存泄漏导致我的Android应用程序崩溃?

拥有json_data_response_object的宽范围是没有意义的,因为在匿名线程之外访问它是危险的(尽管在OnTerminate事件处理程序中是可以的)。我建议在匿名线程中声明对象。同样,aReadingThread最好在ExecuteReadingThread内声明,以避免混淆。

最后一点:在方法开头将Result变量GetDeviceData设置为nil,以保证在所有情况下都分配有效值。