android - Delphi Android RESTRequest: channel 无法恢复,将被丢弃

标签 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)' ~ Channel is unrecoverably broken and will be disposed!



我发现它通常在应用程序中指示内存泄漏,但是我对如何防止它发生一无所知。
  • 在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应用程序崩溃?

    最佳答案

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

    在ARC内存模型下,当对象超出范围时,将自动将其丢弃。但是在这里,在调用ExecuteReadingThread之间并不会超出范围。取而代之的是,对象的指针会不断被覆盖,直到没有剩余的内存(大量泄漏)为止。

    How can I avoid these random Memory Leaks from crashing my Android application?



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

    最后一点:在方法开始时,将ResultGetDeviceData变量设置为nil,以确保在所有情况下均分配有效值。

    关于android - Delphi Android RESTRequest: channel 无法恢复,将被丢弃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38131211/

    相关文章:

    android - FragmentManager 中的内存泄漏

    android - getDrawingCache() 返回 null

    ios - 从 Swift 函数中的异步调用返回数据

    delphi - 如何使用 ReadProcessMemory 读取 pchar

    android - 无法解析 github 库 Android gradle

    android - 如何绘制矩形对象的网格?

    java - Jackson 功能 ACCEPT_SINGLE_VALUE_AS_ARRAY 不适用于注释

    node.js - 覆盖 sails GET 多对一蓝图

    delphi - 如果 DirectShow 渲染器的输入引脚不支持 IAMBufferNegotiation,如何更改其缓冲区大小?

    delphi - 如何将 TRTTIInstanceType obj 引用转换为其实际对象引用?